aboutsummaryrefslogtreecommitdiff
path: root/src/lj_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_api.c')
-rw-r--r--src/lj_api.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/lj_api.c b/src/lj_api.c
index 4b7847c8..961e5150 100644
--- a/src/lj_api.c
+++ b/src/lj_api.c
@@ -1056,19 +1056,32 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1056LUA_API int lua_yield(lua_State *L, int nresults) 1056LUA_API int lua_yield(lua_State *L, int nresults)
1057{ 1057{
1058 void *cf = L->cframe; 1058 void *cf = L->cframe;
1059 cTValue *f; 1059 global_State *g = G(L);
1060 if (!cframe_canyield(cf)) 1060 if (cframe_canyield(cf)) {
1061 lj_err_msg(L, LJ_ERR_CYIELD); 1061 cf = cframe_raw(cf);
1062 f = L->top - nresults; 1062 if (!hook_active(g)) { /* Regular yield: move results down if needed. */
1063 if (f > L->base) { 1063 cTValue *f = L->top - nresults;
1064 TValue *t = L->base; 1064 if (f > L->base) {
1065 while (--nresults >= 0) copyTV(L, t++, f++); 1065 TValue *t = L->base;
1066 L->top = t; 1066 while (--nresults >= 0) copyTV(L, t++, f++);
1067 L->top = t;
1068 }
1069 } else { /* Yield from hook: add a pseudo-frame. */
1070 TValue *top = L->top;
1071 hook_leave(g);
1072 top->u64 = cframe_multres(cf);
1073 setcont(top+1, lj_cont_hook);
1074 setframe_pc(top+1, cframe_pc(cf)-1);
1075 setframe_gc(top+2, obj2gco(L));
1076 top[2].fr.tp.ftsz = cast_int((char *)(top+3)-(char *)L->base)+FRAME_CONT;
1077 L->top = L->base = top+3;
1078 }
1079 L->cframe = NULL;
1080 L->status = LUA_YIELD;
1081 lj_vm_unwind_c(cf, LUA_YIELD);
1067 } 1082 }
1068 L->cframe = NULL; 1083 lj_err_msg(L, LJ_ERR_CYIELD);
1069 L->status = LUA_YIELD; 1084 return 0; /* unreachable */
1070 lj_vm_unwind_c(cf, LUA_YIELD);
1071 return -1; /* unreachable */
1072} 1085}
1073 1086
1074LUA_API int lua_resume(lua_State *L, int nargs) 1087LUA_API int lua_resume(lua_State *L, int nargs)