diff options
| -rw-r--r-- | ldo.c | 19 | ||||
| -rw-r--r-- | ldo.h | 15 | ||||
| -rw-r--r-- | lvm.c | 4 |
3 files changed, 24 insertions, 14 deletions
| @@ -486,20 +486,19 @@ static void moveparams (lua_State *L, StkId prevf, StkId func) { | |||
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | 488 | ||
| 489 | static CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults, | 489 | static CallInfo *prepCallInfo (lua_State *L, StkId func, int retdel, |
| 490 | int delta1, int mask) { | 490 | int mask) { |
| 491 | CallInfo *ci; | 491 | CallInfo *ci; |
| 492 | if (delta1) { /* tail call? */ | 492 | if (isdelta(retdel)) { /* tail call? */ |
| 493 | ci = L->ci; /* reuse stack frame */ | 493 | ci = L->ci; /* reuse stack frame */ |
| 494 | ci->func -= delta1 - 1; /* correct 'func' */ | 494 | ci->func -= retdel2delta(retdel); /* correct 'func' */ |
| 495 | |||
| 496 | ci->callstatus |= mask | CIST_TAIL; | 495 | ci->callstatus |= mask | CIST_TAIL; |
| 497 | moveparams(L, ci->func, func); | 496 | moveparams(L, ci->func, func); |
| 498 | } | 497 | } |
| 499 | else { /* regular call */ | 498 | else { /* regular call */ |
| 500 | ci = L->ci = next_ci(L); /* new frame */ | 499 | ci = L->ci = next_ci(L); /* new frame */ |
| 501 | ci->func = func; | 500 | ci->func = func; |
| 502 | ci->nresults = nresults; | 501 | ci->nresults = retdel; |
| 503 | ci->callstatus = mask; | 502 | ci->callstatus = mask; |
| 504 | } | 503 | } |
| 505 | return ci; | 504 | return ci; |
| @@ -518,7 +517,7 @@ static CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults, | |||
| 518 | ** cannot be zero. Like 'moveparams', this correction can only be done | 517 | ** cannot be zero. Like 'moveparams', this correction can only be done |
| 519 | ** when no more errors can occur in the call. | 518 | ** when no more errors can occur in the call. |
| 520 | */ | 519 | */ |
| 521 | CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) { | 520 | CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) { |
| 522 | lua_CFunction f; | 521 | lua_CFunction f; |
| 523 | retry: | 522 | retry: |
| 524 | switch (ttypetag(s2v(func))) { | 523 | switch (ttypetag(s2v(func))) { |
| @@ -531,7 +530,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) { | |||
| 531 | int n; /* number of returns */ | 530 | int n; /* number of returns */ |
| 532 | CallInfo *ci; | 531 | CallInfo *ci; |
| 533 | checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | 532 | checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
| 534 | ci = prepCallInfo(L, func, nresults, delta1, CIST_C); | 533 | ci = prepCallInfo(L, func, retdel, CIST_C); |
| 535 | ci->top = L->top + LUA_MINSTACK; | 534 | ci->top = L->top + LUA_MINSTACK; |
| 536 | lua_assert(ci->top <= L->stack_last); | 535 | lua_assert(ci->top <= L->stack_last); |
| 537 | if (l_unlikely(L->hookmask & LUA_MASKCALL)) { | 536 | if (l_unlikely(L->hookmask & LUA_MASKCALL)) { |
| @@ -552,7 +551,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, int delta1) { | |||
| 552 | int nfixparams = p->numparams; | 551 | int nfixparams = p->numparams; |
| 553 | int fsize = p->maxstacksize; /* frame size */ | 552 | int fsize = p->maxstacksize; /* frame size */ |
| 554 | checkstackGCp(L, fsize, func); | 553 | checkstackGCp(L, fsize, func); |
| 555 | ci = prepCallInfo(L, func, nresults, delta1, 0); | 554 | ci = prepCallInfo(L, func, retdel, 0); |
| 556 | ci->u.l.savedpc = p->code; /* starting point */ | 555 | ci->u.l.savedpc = p->code; /* starting point */ |
| 557 | ci->top = func + 1 + fsize; | 556 | ci->top = func + 1 + fsize; |
| 558 | for (; narg < nfixparams; narg++) | 557 | for (; narg < nfixparams; narg++) |
| @@ -579,7 +578,7 @@ static void ccall (lua_State *L, StkId func, int nResults, int inc) { | |||
| 579 | L->nCcalls += inc; | 578 | L->nCcalls += inc; |
| 580 | if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) | 579 | if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) |
| 581 | luaE_checkcstack(L); | 580 | luaE_checkcstack(L); |
| 582 | if ((ci = luaD_precall(L, func, nResults, 0)) != NULL) { /* Lua function? */ | 581 | if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ |
| 583 | ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ | 582 | ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ |
| 584 | luaV_execute(L, ci); /* call it */ | 583 | luaV_execute(L, ci); /* call it */ |
| 585 | } | 584 | } |
| @@ -49,6 +49,18 @@ | |||
| 49 | luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) | 49 | luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | /* | ||
| 53 | ** 'luaD_precall' is used for regular calls, when it needs the | ||
| 54 | ** number of results, and in tail calls, when it needs the 'delta' | ||
| 55 | ** (correction of base for vararg functions). The argument 'retdel' | ||
| 56 | ** codes these two options. A number of results is represented by | ||
| 57 | ** itself, while a delta is represented by 'delta2retdel(delta)' | ||
| 58 | */ | ||
| 59 | #define delta2retdel(d) (-(d) + LUA_MULTRET - 1) | ||
| 60 | #define retdel2delta(d) (-(d) + LUA_MULTRET - 1) | ||
| 61 | #define isdelta(rd) ((rd) < LUA_MULTRET) | ||
| 62 | |||
| 63 | |||
| 52 | /* type of protected functions, to be ran by 'runprotected' */ | 64 | /* type of protected functions, to be ran by 'runprotected' */ |
| 53 | typedef void (*Pfunc) (lua_State *L, void *ud); | 65 | typedef void (*Pfunc) (lua_State *L, void *ud); |
| 54 | 66 | ||
| @@ -58,8 +70,7 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | |||
| 58 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, | 70 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, |
| 59 | int fTransfer, int nTransfer); | 71 | int fTransfer, int nTransfer); |
| 60 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); | 72 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); |
| 61 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nresults, | 73 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int retdel); |
| 62 | int delta1); | ||
| 63 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | 74 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); |
| 64 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | 75 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); |
| 65 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); | 76 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); |
| @@ -1632,7 +1632,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1632 | L->top = ra + b; /* top signals number of arguments */ | 1632 | L->top = ra + b; /* top signals number of arguments */ |
| 1633 | /* else previous instruction set top */ | 1633 | /* else previous instruction set top */ |
| 1634 | savepc(L); /* in case of errors */ | 1634 | savepc(L); /* in case of errors */ |
| 1635 | if ((newci = luaD_precall(L, ra, nresults, 0)) == NULL) | 1635 | if ((newci = luaD_precall(L, ra, nresults)) == NULL) |
| 1636 | updatetrap(ci); /* C call; nothing else to be done */ | 1636 | updatetrap(ci); /* C call; nothing else to be done */ |
| 1637 | else { /* Lua call: run function in this same C frame */ | 1637 | else { /* Lua call: run function in this same C frame */ |
| 1638 | ci = newci; | 1638 | ci = newci; |
| @@ -1654,7 +1654,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1654 | lua_assert(L->tbclist < base); /* no pending tbc variables */ | 1654 | lua_assert(L->tbclist < base); /* no pending tbc variables */ |
| 1655 | lua_assert(base == ci->func + 1); | 1655 | lua_assert(base == ci->func + 1); |
| 1656 | } | 1656 | } |
| 1657 | if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) /* Lua function? */ | 1657 | if (luaD_precall(L, ra, delta2retdel(delta))) /* Lua function? */ |
| 1658 | goto startfunc; /* execute the callee */ | 1658 | goto startfunc; /* execute the callee */ |
| 1659 | else { /* C function */ | 1659 | else { /* C function */ |
| 1660 | updatetrap(ci); | 1660 | updatetrap(ci); |
