summaryrefslogtreecommitdiff
path: root/libs/liblua/src/lvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/liblua/src/lvm.c')
-rw-r--r--libs/liblua/src/lvm.c75
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? */