diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 19 |
1 files changed, 5 insertions, 14 deletions
@@ -1643,6 +1643,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1643 | } | 1643 | } |
1644 | vmcase(OP_TAILCALL) { | 1644 | vmcase(OP_TAILCALL) { |
1645 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ | 1645 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ |
1646 | int n; /* number of results when calling a C function */ | ||
1646 | int nparams1 = GETARG_C(i); | 1647 | int nparams1 = GETARG_C(i); |
1647 | /* delta is virtual 'func' - real 'func' (vararg functions) */ | 1648 | /* delta is virtual 'func' - real 'func' (vararg functions) */ |
1648 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; | 1649 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; |
@@ -1656,24 +1657,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1656 | lua_assert(L->tbclist < base); /* no pending tbc variables */ | 1657 | lua_assert(L->tbclist < base); /* no pending tbc variables */ |
1657 | lua_assert(base == ci->func + 1); | 1658 | lua_assert(base == ci->func + 1); |
1658 | } | 1659 | } |
1659 | while (!ttisfunction(s2v(ra))) { /* not a function? */ | 1660 | if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */ |
1660 | ra = luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ | 1661 | goto startfunc; /* execute the callee */ |
1661 | b++; /* there is now one extra argument */ | 1662 | else { /* C function? */ |
1662 | } | ||
1663 | if (!ttisLclosure(s2v(ra))) { /* C function? */ | ||
1664 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ | ||
1665 | updatetrap(ci); | ||
1666 | updatestack(ci); /* stack may have been relocated */ | ||
1667 | ci->func -= delta; /* restore 'func' (if vararg) */ | 1663 | ci->func -= delta; /* restore 'func' (if vararg) */ |
1668 | luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ | 1664 | luaD_poscall(L, ci, n); /* finish caller */ |
1669 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ | 1665 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ |
1670 | goto ret; /* caller returns after the tail call */ | 1666 | goto ret; /* caller returns after the tail call */ |
1671 | } | 1667 | } |
1672 | else { /* Lua function */ | ||
1673 | ci->func -= delta; /* restore 'func' (if vararg) */ | ||
1674 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | ||
1675 | goto startfunc; /* execute the callee */ | ||
1676 | } | ||
1677 | } | 1668 | } |
1678 | vmcase(OP_RETURN) { | 1669 | vmcase(OP_RETURN) { |
1679 | int n = GETARG_B(i) - 1; /* number of results */ | 1670 | int n = GETARG_B(i) - 1; /* number of results */ |