diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 21 |
1 files changed, 17 insertions, 4 deletions
@@ -768,6 +768,7 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { | |||
768 | */ | 768 | */ |
769 | #define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) | 769 | #define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) |
770 | 770 | ||
771 | |||
771 | lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { | 772 | lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { |
772 | if (y < 0) { /* shift right? */ | 773 | if (y < 0) { /* shift right? */ |
773 | if (y <= -NBITS) return 0; | 774 | if (y <= -NBITS) return 0; |
@@ -1647,19 +1648,31 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1647 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; | 1648 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; |
1648 | if (b != 0) | 1649 | if (b != 0) |
1649 | L->top = ra + b; | 1650 | L->top = ra + b; |
1650 | /* else previous instruction set top */ | 1651 | else /* previous instruction set top */ |
1652 | b = cast_int(L->top - ra); | ||
1651 | savepc(ci); /* several calls here can raise errors */ | 1653 | savepc(ci); /* several calls here can raise errors */ |
1652 | if (TESTARG_k(i)) { | 1654 | if (TESTARG_k(i)) { |
1653 | luaF_closeupval(L, base); /* close upvalues from current call */ | 1655 | luaF_closeupval(L, base); /* close upvalues from current call */ |
1654 | lua_assert(L->tbclist < base); /* no pending tbc variables */ | 1656 | lua_assert(L->tbclist < base); /* no pending tbc variables */ |
1655 | lua_assert(base == ci->func + 1); | 1657 | lua_assert(base == ci->func + 1); |
1656 | } | 1658 | } |
1657 | if (luaD_precall(L, ra, delta2retdel(delta))) /* Lua function? */ | 1659 | while (!ttisfunction(s2v(ra))) { /* not a function? */ |
1658 | goto startfunc; /* execute the callee */ | 1660 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ |
1659 | else { /* C function */ | 1661 | b++; /* there is now one extra argument */ |
1662 | checkstackGCp(L, 1, ra); | ||
1663 | } | ||
1664 | if (!ttisLclosure(s2v(ra))) { /* C function? */ | ||
1665 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ | ||
1660 | updatetrap(ci); | 1666 | updatetrap(ci); |
1667 | updatestack(ci); /* stack may have been relocated */ | ||
1668 | ci->func -= delta; /* restore 'func' (if vararg) */ | ||
1669 | luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ | ||
1670 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ | ||
1661 | goto ret; /* caller returns after the tail call */ | 1671 | goto ret; /* caller returns after the tail call */ |
1662 | } | 1672 | } |
1673 | ci->func -= delta; /* restore 'func' (if vararg) */ | ||
1674 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | ||
1675 | goto startfunc; /* execute the callee */ | ||
1663 | } | 1676 | } |
1664 | vmcase(OP_RETURN) { | 1677 | vmcase(OP_RETURN) { |
1665 | int n = GETARG_B(i) - 1; /* number of results */ | 1678 | int n = GETARG_B(i) - 1; /* number of results */ |