** Completes the execution of a C function interrupted by an yield. ** The interruption must have happened while the function was either ** closing its tbc variables in 'moveresults' or executing ** 'lua_callk'/'lua_pcallk'. In the first case, it just redoes ** 'luaD_poscall'. In the second case, the call to 'finishpcallk' ** finishes the interrupted execution of 'lua_pcallk'. After that, it ** c
| 647 | ** conservative and use LUA_MULTRET (always adjust). |
| 648 | */ |
| 649 | static void finishCcall (lua_State *L, CallInfo *ci) { |
| 650 | int n; /* actual number of results from C function */ |
| 651 | if (ci->callstatus & CIST_CLSRET) { /* was returning? */ |
| 652 | lua_assert(hastocloseCfunc(ci->nresults)); |
| 653 | n = ci->u2.nres; /* just redo 'luaD_poscall' */ |
| 654 | /* don't need to reset CIST_CLSRET, as it will be set again anyway */ |
| 655 | } |
| 656 | else { |
| 657 | int status = LUA_YIELD; /* default if there were no errors */ |
| 658 | /* must have a continuation and must be able to call it */ |
| 659 | lua_assert(ci->u.c.k != NULL && yieldable(L)); |
| 660 | if (ci->callstatus & CIST_YPCALL) /* was inside a 'lua_pcallk'? */ |
| 661 | status = finishpcallk(L, ci); /* finish it */ |
| 662 | adjustresults(L, LUA_MULTRET); /* finish 'lua_callk' */ |
| 663 | lua_unlock(L); |
| 664 | n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation */ |
| 665 | lua_lock(L); |
| 666 | api_checknelems(L, n); |
| 667 | } |
| 668 | luaD_poscall(L, ci, n); /* finish 'luaD_call' */ |
| 669 | } |
| 670 | |
| 671 | |
| 672 | /* |
no test coverage detected