public static void lua_callk(lua_State L, int nargs, int nresults, lua_Ctx ctx, lua_KFunction k) { StkId func; lua_lock(L); api_check(k == null || isLua(L.ci) == 0, "cannot use continuations inside hooks"); api_checknelems(L, nargs + 1); api_check(L.status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); func = L.top - (nargs + 1); if (k != null && L.nny == 0) /* need to prepare continuation? */ { L.ci.u.c.k = k; /* save continuation */ L.ci.u.c.ctx = ctx; /* save context */ luaD_call(L, func, nresults, 1); /* do the call */ } else /* no continuation or no yieldable */ { luaD_call(L, func, nresults, 0); /* just do the call */ } adjustresults(L, nresults); lua_unlock(L); }
/* ** Continuation function for 'pcall' and 'xpcall'. Both functions ** already pushed a 'true' before doing the call, so in case of success ** 'finishpcall' only has to return everything in the stack minus ** 'extra' values (where 'extra' is exactly the number of items to be ** ignored). */ private static int finishpcall(lua_State L, int status, lua_Ctx extra) { if (status != LUA_OK && status != LUA_YIELD) /* error? */ { lua_pushboolean(L, 0); /* first result (false) */ lua_pushvalue(L, -2); /* error message */ return(2); /* return false, msg */ } else { return(lua_gettop(L) - extra); /* return all results */ } }
public static int lua_pcallk(lua_State L, int nargs, int nresults, int errfunc, lua_Ctx ctx, lua_KFunction k) { CallS c = new CallS(); int status; ptrdiff_t func; lua_lock(L); api_check(k == null || isLua(L.ci) == 0, "cannot use continuations inside hooks"); api_checknelems(L, nargs + 1); api_check(L.status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); if (errfunc == 0) { func = 0; } else { StkId o = index2addr(L, errfunc); api_checkstackindex(errfunc, o); func = savestack(L, o); } c.func = L.top - (nargs + 1); /* function to be called */ if (k == null || L.nny > 0) /* no continuation or no yieldable? */ { c.nresults = nresults; /* do a 'conventional' protected call */ status = luaD_pcall(L, f_call, c, savestack(L, c.func), func); } else /* prepare continuation (call is already protected by 'resume') */ { CallInfo ci = L.ci; ci.u.c.k = k; /* save continuation */ ci.u.c.ctx = ctx; /* save context */ /* save information for error recovery */ ci.extra = savestack(L, c.func); ci.u.c.old_errfunc = L.errfunc; L.errfunc = func; setoah(ci.callstatus, L.allowhook); /* save value of 'allowhook' */ ci.callstatus |= CIST_YPCALL; /* function can do error recovery */ luaD_call(L, c.func, nresults, 1); /* do the call */ ci.callstatus &= (byte)((~CIST_YPCALL) & 0xff); L.errfunc = ci.u.c.old_errfunc; status = LUA_OK; /* if it is here, there were no errors */ } adjustresults(L, nresults); lua_unlock(L); return(status); }
public static int lua_yieldk(lua_State L, int nresults, lua_Ctx ctx, lua_KFunction k) { CallInfo ci = L.ci; luai_userstateyield(L, nresults); lua_lock(L); api_checknelems(L, nresults); if (L.nny > 0) { if (L != G(L).mainthread) { luaG_runerror(L, "attempt to yield across a C-call boundary"); } else { luaG_runerror(L, "attempt to yield from outside a coroutine"); } } L.status = LUA_YIELD; ci.extra = savestack(L, ci.func); /* save current 'func' */ if (isLua(ci) != 0) /* inside a hook? */ { api_check(k == null, "hooks cannot continue after yielding"); } else { if ((ci.u.c.k = k) != null) /* is there a continuation? */ { ci.u.c.ctx = ctx; /* save context */ } ci.func = L.top - nresults - 1; /* protect stack below results */ luaD_throw(L, LUA_YIELD); } lua_assert(ci.callstatus & CIST_HOOKED); /* must be inside a hook */ lua_unlock(L); return(0); /* return to 'luaD_hook' */ }
/* }====================================================== */ private static int dofilecont(lua_State L, int d1, lua_Ctx d2) { //(void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */ return(lua_gettop(L) - 1); }