diff options
Diffstat (limited to 'libs/liblua/src/lvm.c')
-rw-r--r-- | libs/liblua/src/lvm.c | 75 |
1 files changed, 47 insertions, 28 deletions
diff --git a/libs/liblua/src/lvm.c b/libs/liblua/src/lvm.c index 08681af1b8..aa3b22bf73 100644 --- a/libs/liblua/src/lvm.c +++ b/libs/liblua/src/lvm.c @@ -229,7 +229,7 @@ static int forprep (lua_State *L, StkId ra) { count /= l_castS2U(-(step + 1)) + 1u; } /* store the counter in place of the limit (which won't be - needed anymore */ + needed anymore) */ setivalue(plimit, l_castU2S(count)); } } @@ -1092,15 +1092,11 @@ void luaV_finishOp (lua_State *L) { #define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) /* -** Protect code that will finish the loop (returns) or can only raise -** errors. (That is, it will not return to the interpreter main loop -** after changing the stack or hooks.) +** Protect code that can only raise errors. (That is, it cannnot change +** the stack or hooks.) */ #define halfProtect(exp) (savestate(L,ci), (exp)) -/* idem, but without changing the stack */ -#define halfProtectNT(exp) (savepc(L), (exp)) - /* 'c' is the limit of live values in the stack */ #define checkGC(L,c) \ { luaC_condGC(L, (savepc(L), L->top = (c)), \ @@ -1132,17 +1128,20 @@ void luaV_execute (lua_State *L, CallInfo *ci) { #if LUA_USE_JUMPTABLE #include "ljumptab.h" #endif - tailcall: + startfunc: trap = L->hookmask; + returning: /* trap already set */ cl = clLvalue(s2v(ci->func)); k = cl->p->k; pc = ci->u.l.savedpc; if (trap) { - if (cl->p->is_vararg) - trap = 0; /* hooks will start after VARARGPREP instruction */ - else if (pc == cl->p->code) /* first instruction (not resuming)? */ - luaD_hookcall(L, ci); - ci->u.l.trap = 1; /* there may be other hooks */ + if (pc == cl->p->code) { /* first instruction (not resuming)? */ + if (cl->p->is_vararg) + trap = 0; /* hooks will start after VARARGPREP instruction */ + else /* check 'call' hook */ + luaD_hookcall(L, ci); + } + ci->u.l.trap = 1; /* assume trap is on, for now */ } base = ci->func + 1; /* main loop of interpreter */ @@ -1151,7 +1150,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { StkId ra; /* instruction's A register */ vmfetch(); lua_assert(base == ci->func + 1); - lua_assert(base <= L->top && L->top < L->stack + L->stacksize); + lua_assert(base <= L->top && L->top < L->stack_last); /* invalidate top for instructions not expecting it */ lua_assert(isIT(i) || (cast_void(L->top = base), 1)); vmdispatch (GET_OPCODE(i)) { @@ -1606,24 +1605,32 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_CALL) { + CallInfo *newci; int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) /* fixed number of arguments? */ L->top = ra + b; /* top signals number of arguments */ /* else previous instruction set top */ - ProtectNT(luaD_call(L, ra, nresults)); + savepc(L); /* in case of errors */ + if ((newci = luaD_precall(L, ra, nresults)) == NULL) + updatetrap(ci); /* C call; nothing else to be done */ + else { /* Lua call: run function in this same C frame */ + ci = newci; + ci->callstatus = 0; /* call re-uses 'luaV_execute' */ + goto startfunc; + } vmbreak; } vmcase(OP_TAILCALL) { int b = GETARG_B(i); /* number of arguments + 1 (function) */ int nparams1 = GETARG_C(i); - /* delat is virtual 'func' - real 'func' (vararg functions) */ + /* delta is virtual 'func' - real 'func' (vararg functions) */ int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; if (b != 0) L->top = ra + b; else /* previous instruction set top */ b = cast_int(L->top - ra); - savepc(ci); /* some calls here can raise errors */ + savepc(ci); /* several calls here can raise errors */ if (TESTARG_k(i)) { /* close upvalues from current call; the compiler ensures that there are no to-be-closed variables here, so this @@ -1637,16 +1644,17 @@ void luaV_execute (lua_State *L, CallInfo *ci) { checkstackGCp(L, 1, ra); } if (!ttisLclosure(s2v(ra))) { /* C function? */ - luaD_call(L, ra, LUA_MULTRET); /* call it */ + luaD_precall(L, ra, LUA_MULTRET); /* call it */ updatetrap(ci); updatestack(ci); /* stack may have been relocated */ - ci->func -= delta; - luaD_poscall(L, ci, cast_int(L->top - ra)); - return; + ci->func -= delta; /* restore 'func' (if vararg) */ + luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ + updatetrap(ci); /* 'luaD_poscall' can change hooks */ + goto ret; /* caller returns after the tail call */ } - ci->func -= delta; + ci->func -= delta; /* restore 'func' (if vararg) */ luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ - goto tailcall; + goto startfunc; /* execute the callee */ } vmcase(OP_RETURN) { int n = GETARG_B(i) - 1; /* number of results */ @@ -1665,12 +1673,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { ci->func -= ci->u.l.nextraargs + nparams1; L->top = ra + n; /* set call for 'luaD_poscall' */ luaD_poscall(L, ci, n); - return; + updatetrap(ci); /* 'luaD_poscall' can change hooks */ + goto ret; } vmcase(OP_RETURN0) { if (L->hookmask) { L->top = ra; - halfProtectNT(luaD_poscall(L, ci, 0)); /* no hurry... */ + savepc(ci); + luaD_poscall(L, ci, 0); /* no hurry... */ + trap = 1; } else { /* do the 'poscall' here */ int nres = ci->nresults; @@ -1679,12 +1690,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { while (nres-- > 0) setnilvalue(s2v(L->top++)); /* all results are nil */ } - return; + goto ret; } vmcase(OP_RETURN1) { if (L->hookmask) { L->top = ra + 1; - halfProtectNT(luaD_poscall(L, ci, 1)); /* no hurry... */ + savepc(ci); + luaD_poscall(L, ci, 1); /* no hurry... */ + trap = 1; } else { /* do the 'poscall' here */ int nres = ci->nresults; @@ -1698,7 +1711,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { setnilvalue(s2v(L->top++)); } } - return; + ret: /* return from a Lua function */ + if (ci->callstatus & CIST_FRESH) + return; /* end this frame */ + else { + ci = ci->previous; + goto returning; /* continue running caller in this frame */ + } } vmcase(OP_FORLOOP) { if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ |