Implement yield from C hooks.

Get number of multiple results from C frame.
Add lj_cont_hook: restores multres and dispatch to static ins.
Can use fastcall for lj_dispatch_ins() now.
This commit is contained in:
Mike Pall
2009-12-30 02:37:57 +01:00
parent 52eb88773e
commit 9de0f53a8d
9 changed files with 956 additions and 938 deletions

View File

@@ -1056,19 +1056,32 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
LUA_API int lua_yield(lua_State *L, int nresults)
{
void *cf = L->cframe;
cTValue *f;
if (!cframe_canyield(cf))
lj_err_msg(L, LJ_ERR_CYIELD);
f = L->top - nresults;
if (f > L->base) {
TValue *t = L->base;
while (--nresults >= 0) copyTV(L, t++, f++);
L->top = t;
global_State *g = G(L);
if (cframe_canyield(cf)) {
cf = cframe_raw(cf);
if (!hook_active(g)) { /* Regular yield: move results down if needed. */
cTValue *f = L->top - nresults;
if (f > L->base) {
TValue *t = L->base;
while (--nresults >= 0) copyTV(L, t++, f++);
L->top = t;
}
} else { /* Yield from hook: add a pseudo-frame. */
TValue *top = L->top;
hook_leave(g);
top->u64 = cframe_multres(cf);
setcont(top+1, lj_cont_hook);
setframe_pc(top+1, cframe_pc(cf)-1);
setframe_gc(top+2, obj2gco(L));
top[2].fr.tp.ftsz = cast_int((char *)(top+3)-(char *)L->base)+FRAME_CONT;
L->top = L->base = top+3;
}
L->cframe = NULL;
L->status = LUA_YIELD;
lj_vm_unwind_c(cf, LUA_YIELD);
}
L->cframe = NULL;
L->status = LUA_YIELD;
lj_vm_unwind_c(cf, LUA_YIELD);
return -1; /* unreachable */
lj_err_msg(L, LJ_ERR_CYIELD);
return 0; /* unreachable */
}
LUA_API int lua_resume(lua_State *L, int nargs)