diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 25 |
1 files changed, 13 insertions, 12 deletions
@@ -1124,7 +1124,6 @@ void luaV_finishOp (lua_State *L) { | |||
1124 | 1124 | ||
1125 | 1125 | ||
1126 | void luaV_execute (lua_State *L, CallInfo *ci) { | 1126 | void luaV_execute (lua_State *L, CallInfo *ci) { |
1127 | CallInfo * const origci = ci; | ||
1128 | LClosure *cl; | 1127 | LClosure *cl; |
1129 | TValue *k; | 1128 | TValue *k; |
1130 | StkId base; | 1129 | StkId base; |
@@ -1133,7 +1132,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1133 | #if LUA_USE_JUMPTABLE | 1132 | #if LUA_USE_JUMPTABLE |
1134 | #include "ljumptab.h" | 1133 | #include "ljumptab.h" |
1135 | #endif | 1134 | #endif |
1136 | tailcall: | 1135 | execute: |
1137 | trap = L->hookmask; | 1136 | trap = L->hookmask; |
1138 | cl = clLvalue(s2v(ci->func)); | 1137 | cl = clLvalue(s2v(ci->func)); |
1139 | k = cl->p->k; | 1138 | k = cl->p->k; |
@@ -1607,17 +1606,19 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1607 | vmbreak; | 1606 | vmbreak; |
1608 | } | 1607 | } |
1609 | vmcase(OP_CALL) { | 1608 | vmcase(OP_CALL) { |
1609 | CallInfo *newci; | ||
1610 | int b = GETARG_B(i); | 1610 | int b = GETARG_B(i); |
1611 | int nresults = GETARG_C(i) - 1; | 1611 | int nresults = GETARG_C(i) - 1; |
1612 | if (b != 0) /* fixed number of arguments? */ | 1612 | if (b != 0) /* fixed number of arguments? */ |
1613 | L->top = ra + b; /* top signals number of arguments */ | 1613 | L->top = ra + b; /* top signals number of arguments */ |
1614 | /* else previous instruction set top */ | 1614 | /* else previous instruction set top */ |
1615 | savepc(L); /* in case of errors */ | 1615 | savepc(L); /* in case of errors */ |
1616 | if (luaD_precall(L, ra, nresults)) | 1616 | if ((newci = luaD_precall(L, ra, nresults)) == NULL) |
1617 | updatetrap(ci); /* C call; nothing else to be done */ | 1617 | updatetrap(ci); /* C call; nothing else to be done */ |
1618 | else { /* Lua call: run function in this same invocation */ | 1618 | else { /* Lua call: run function in this same invocation */ |
1619 | ci = L->ci; | 1619 | ci = newci; |
1620 | goto tailcall; | 1620 | ci->callstatus = 0; /* call re-uses 'luaV_execute' */ |
1621 | goto execute; | ||
1621 | } | 1622 | } |
1622 | vmbreak; | 1623 | vmbreak; |
1623 | } | 1624 | } |
@@ -1647,13 +1648,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1647 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ | 1648 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ |
1648 | updatetrap(ci); | 1649 | updatetrap(ci); |
1649 | updatestack(ci); /* stack may have been relocated */ | 1650 | updatestack(ci); /* stack may have been relocated */ |
1650 | ci->func -= delta; | 1651 | ci->func -= delta; /* restore 'func' (if vararg) */ |
1651 | luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ | 1652 | luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ |
1652 | goto ret; | 1653 | goto ret; /* caller returns after the tail call */ |
1653 | } | 1654 | } |
1654 | ci->func -= delta; | 1655 | ci->func -= delta; /* restore 'func' (if vararg) */ |
1655 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | 1656 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ |
1656 | goto tailcall; | 1657 | goto execute; /* execute the callee */ |
1657 | } | 1658 | } |
1658 | vmcase(OP_RETURN) { | 1659 | vmcase(OP_RETURN) { |
1659 | int n = GETARG_B(i) - 1; /* number of results */ | 1660 | int n = GETARG_B(i) - 1; /* number of results */ |
@@ -1706,11 +1707,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1706 | } | 1707 | } |
1707 | } | 1708 | } |
1708 | ret: | 1709 | ret: |
1709 | if (ci == origci) | 1710 | if (ci->callstatus & CIST_FRESH) |
1710 | return; | 1711 | return; /* end this frame */ |
1711 | else { | 1712 | else { |
1712 | ci = ci->previous; | 1713 | ci = ci->previous; |
1713 | goto tailcall; | 1714 | goto execute; /* continue running caller in this frame */ |
1714 | } | 1715 | } |
1715 | } | 1716 | } |
1716 | vmcase(OP_FORLOOP) { | 1717 | vmcase(OP_FORLOOP) { |