diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -229,7 +229,7 @@ static int forprep (lua_State *L, StkId ra) { | |||
229 | count /= l_castS2U(-(step + 1)) + 1u; | 229 | count /= l_castS2U(-(step + 1)) + 1u; |
230 | } | 230 | } |
231 | /* store the counter in place of the limit (which won't be | 231 | /* store the counter in place of the limit (which won't be |
232 | needed anymore */ | 232 | needed anymore) */ |
233 | setivalue(plimit, l_castU2S(count)); | 233 | setivalue(plimit, l_castU2S(count)); |
234 | } | 234 | } |
235 | } | 235 | } |
@@ -1124,6 +1124,7 @@ 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 | const CallInfo *origci = ci; | ||
1127 | LClosure *cl; | 1128 | LClosure *cl; |
1128 | TValue *k; | 1129 | TValue *k; |
1129 | StkId base; | 1130 | StkId base; |
@@ -1611,7 +1612,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1611 | if (b != 0) /* fixed number of arguments? */ | 1612 | if (b != 0) /* fixed number of arguments? */ |
1612 | L->top = ra + b; /* top signals number of arguments */ | 1613 | L->top = ra + b; /* top signals number of arguments */ |
1613 | /* else previous instruction set top */ | 1614 | /* else previous instruction set top */ |
1614 | ProtectNT(luaD_call(L, ra, nresults)); | 1615 | savepc(L); /* in case of errors */ |
1616 | if (luaD_precall(L, ra, nresults)) | ||
1617 | updatetrap(ci); /* C call; nothing else to be done */ | ||
1618 | else { /* Lua call: run function in this same invocation */ | ||
1619 | ci = L->ci; | ||
1620 | goto tailcall; | ||
1621 | } | ||
1615 | vmbreak; | 1622 | vmbreak; |
1616 | } | 1623 | } |
1617 | vmcase(OP_TAILCALL) { | 1624 | vmcase(OP_TAILCALL) { |
@@ -1637,12 +1644,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1637 | checkstackGCp(L, 1, ra); | 1644 | checkstackGCp(L, 1, ra); |
1638 | } | 1645 | } |
1639 | if (!ttisLclosure(s2v(ra))) { /* C function? */ | 1646 | if (!ttisLclosure(s2v(ra))) { /* C function? */ |
1640 | luaD_call(L, ra, LUA_MULTRET); /* call it */ | 1647 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ |
1641 | updatetrap(ci); | 1648 | updatetrap(ci); |
1642 | updatestack(ci); /* stack may have been relocated */ | 1649 | updatestack(ci); /* stack may have been relocated */ |
1643 | ci->func -= delta; | 1650 | ci->func -= delta; |
1644 | luaD_poscall(L, ci, cast_int(L->top - ra)); | 1651 | luaD_poscall(L, ci, cast_int(L->top - ra)); |
1645 | return; | 1652 | goto ret; |
1646 | } | 1653 | } |
1647 | ci->func -= delta; | 1654 | ci->func -= delta; |
1648 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | 1655 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ |
@@ -1665,7 +1672,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1665 | ci->func -= ci->u.l.nextraargs + nparams1; | 1672 | ci->func -= ci->u.l.nextraargs + nparams1; |
1666 | L->top = ra + n; /* set call for 'luaD_poscall' */ | 1673 | L->top = ra + n; /* set call for 'luaD_poscall' */ |
1667 | luaD_poscall(L, ci, n); | 1674 | luaD_poscall(L, ci, n); |
1668 | return; | 1675 | goto ret; |
1669 | } | 1676 | } |
1670 | vmcase(OP_RETURN0) { | 1677 | vmcase(OP_RETURN0) { |
1671 | if (L->hookmask) { | 1678 | if (L->hookmask) { |
@@ -1679,7 +1686,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1679 | while (nres-- > 0) | 1686 | while (nres-- > 0) |
1680 | setnilvalue(s2v(L->top++)); /* all results are nil */ | 1687 | setnilvalue(s2v(L->top++)); /* all results are nil */ |
1681 | } | 1688 | } |
1682 | return; | 1689 | goto ret; |
1683 | } | 1690 | } |
1684 | vmcase(OP_RETURN1) { | 1691 | vmcase(OP_RETURN1) { |
1685 | if (L->hookmask) { | 1692 | if (L->hookmask) { |
@@ -1698,7 +1705,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1698 | setnilvalue(s2v(L->top++)); | 1705 | setnilvalue(s2v(L->top++)); |
1699 | } | 1706 | } |
1700 | } | 1707 | } |
1701 | return; | 1708 | ret: |
1709 | if (ci == origci) | ||
1710 | return; | ||
1711 | else { | ||
1712 | ci = ci->previous; | ||
1713 | goto tailcall; | ||
1714 | } | ||
1702 | } | 1715 | } |
1703 | vmcase(OP_FORLOOP) { | 1716 | vmcase(OP_FORLOOP) { |
1704 | if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ | 1717 | if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ |