| 660 | } |
| 661 | |
| 662 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, |
| 663 | int *nresults) { |
| 664 | int status; |
| 665 | lua_lock(L); |
| 666 | if (L->status == LUA_OK) { /* may be starting a coroutine */ |
| 667 | if (L->ci != &L->base_ci) /* not in base level? */ |
| 668 | return resume_error(L, "cannot resume non-suspended coroutine", nargs); |
| 669 | else if (L->top - (L->ci->func + 1) == nargs) /* no function? */ |
| 670 | return resume_error(L, "cannot resume dead coroutine", nargs); |
| 671 | } |
| 672 | else if (L->status != LUA_YIELD) /* ended with errors? */ |
| 673 | return resume_error(L, "cannot resume dead coroutine", nargs); |
| 674 | if (from == NULL) |
| 675 | L->nCcalls = CSTACKTHREAD; |
| 676 | else /* correct 'nCcalls' for this thread */ |
| 677 | L->nCcalls = getCcalls(from) + from->nci - L->nci - CSTACKCF; |
| 678 | if (L->nCcalls <= CSTACKERR) |
| 679 | return resume_error(L, "C stack overflow", nargs); |
| 680 | luai_userstateresume(L, nargs); |
| 681 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
| 682 | status = luaD_rawrunprotected(L, resume, &nargs); |
| 683 | /* continue running after recoverable errors */ |
| 684 | while (errorstatus(status) && recover(L, status)) { |
| 685 | /* unroll continuation */ |
| 686 | status = luaD_rawrunprotected(L, unroll, &status); |
| 687 | } |
| 688 | if (likely(!errorstatus(status))) |
| 689 | lua_assert(status == L->status); /* normal end or yield */ |
| 690 | else { /* unrecoverable error */ |
| 691 | L->status = cast_byte(status); /* mark thread as 'dead' */ |
| 692 | luaD_seterrorobj(L, status, L->top); /* push error message */ |
| 693 | L->ci->top = L->top; |
| 694 | } |
| 695 | *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield |
| 696 | : cast_int(L->top - (L->ci->func + 1)); |
| 697 | lua_unlock(L); |
| 698 | return status; |
| 699 | } |
| 700 | |
| 701 | |
| 702 | LUA_API int lua_isyieldable (lua_State *L) { |
no test coverage detected