diff --git a/ldo.c b/ldo.c index 38540561..93fcbb1a 100644 --- a/ldo.c +++ b/ldo.c @@ -486,20 +486,19 @@ static void moveparams (lua_State *L, StkId prevf, StkId func) { } -static CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults, - int delta1, int mask) { +static CallInfo *prepCallInfo (lua_State *L, StkId func, int retdel, + int mask) { CallInfo *ci; - if (delta1) { /* tail call? */ + if (isdelta(retdel)) { /* tail call? */ ci = L->ci; /* reuse stack frame */ - ci->func -= delta1 - 1; /* correct 'func' */ - + ci->func -= retdel2delta(retdel); /* correct 'func' */ ci->callstatus |= mask | CIST_TAIL; moveparams(L, ci->func, func); } else { /* regular call */ ci = L->ci = next_ci(L); /* new frame */ ci->func = func; - ci->nresults = nresults; + ci->nresults = retdel; ci->callstatus = mask; } return ci; @@ -518,7 +517,7 @@ static CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults, ** cannot be zero. Like 'moveparams', this correction can only be done ** when no more errors can occur in the call. */ -CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) { +CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) { lua_CFunction f; retry: switch (ttypetag(s2v(func))) { @@ -531,7 +530,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) { int n; /* number of returns */ CallInfo *ci; checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ - ci = prepCallInfo(L, func, nresults, delta1, CIST_C); + ci = prepCallInfo(L, func, retdel, CIST_C); ci->top = L->top + LUA_MINSTACK; lua_assert(ci->top <= L->stack_last); if (l_unlikely(L->hookmask & LUA_MASKCALL)) { @@ -552,7 +551,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) { int nfixparams = p->numparams; int fsize = p->maxstacksize; /* frame size */ checkstackGCp(L, fsize, func); - ci = prepCallInfo(L, func, nresults, delta1, 0); + ci = prepCallInfo(L, func, retdel, 0); ci->u.l.savedpc = p->code; /* starting point */ ci->top = func + 1 + fsize; for (; narg < nfixparams; narg++) @@ -579,7 +578,7 @@ static void ccall (lua_State *L, StkId func, int nResults, int inc) { L->nCcalls += inc; if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) luaE_checkcstack(L); - if ((ci = luaD_precall(L, func, nResults, 0)) != NULL) { /* Lua function? */ + if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ luaV_execute(L, ci); /* call it */ } diff --git a/ldo.h b/ldo.h index 6edc4450..49fbb492 100644 --- a/ldo.h +++ b/ldo.h @@ -49,6 +49,18 @@ luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) +/* +** 'luaD_precall' is used for regular calls, when it needs the +** number of results, and in tail calls, when it needs the 'delta' +** (correction of base for vararg functions). The argument 'retdel' +** codes these two options. A number of results is represented by +** itself, while a delta is represented by 'delta2retdel(delta)' +*/ +#define delta2retdel(d) (-(d) + LUA_MULTRET - 1) +#define retdel2delta(d) (-(d) + LUA_MULTRET - 1) +#define isdelta(rd) ((rd) < LUA_MULTRET) + + /* type of protected functions, to be ran by 'runprotected' */ typedef void (*Pfunc) (lua_State *L, void *ud); @@ -58,8 +70,7 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, int fTransfer, int nTransfer); LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); -LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, - int delta1); +LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int retdel); LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); diff --git a/lvm.c b/lvm.c index 62ff70da..ec83f415 100644 --- a/lvm.c +++ b/lvm.c @@ -1632,7 +1632,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { L->top = ra + b; /* top signals number of arguments */ /* else previous instruction set top */ savepc(L); /* in case of errors */ - if ((newci = luaD_precall(L, ra, nresults, 0)) == NULL) + 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; @@ -1654,7 +1654,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { lua_assert(L->tbclist < base); /* no pending tbc variables */ lua_assert(base == ci->func + 1); } - if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) /* Lua function? */ + if (luaD_precall(L, ra, delta2retdel(delta))) /* Lua function? */ goto startfunc; /* execute the callee */ else { /* C function */ updatetrap(ci);