diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-06-14 13:28:21 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-06-14 13:28:21 -0300 |
commit | 04e19712a5d48b84869f9942836ff8314fb0be8e (patch) | |
tree | 75aab8dff5bdf07026080eba0189e4025ec3b7ee /lvm.c | |
parent | 901d76009346d76996679c02deee708bf225e91e (diff) | |
download | lua-04e19712a5d48b84869f9942836ff8314fb0be8e.tar.gz lua-04e19712a5d48b84869f9942836ff8314fb0be8e.tar.bz2 lua-04e19712a5d48b84869f9942836ff8314fb0be8e.zip |
C functions can be tail called, too
A tail call to a C function can have the behavior of a "real" tail
call, reusing the stack frame of the caller.
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 9 |
1 files changed, 1 insertions, 8 deletions
@@ -1636,7 +1636,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
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; |
1639 | ci->callstatus = 0; | ||
1640 | goto startfunc; | 1639 | goto startfunc; |
1641 | } | 1640 | } |
1642 | vmbreak; | 1641 | vmbreak; |
@@ -1655,16 +1654,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1655 | lua_assert(L->tbclist < base); /* no pending tbc variables */ | 1654 | lua_assert(L->tbclist < base); /* no pending tbc variables */ |
1656 | lua_assert(base == ci->func + 1); | 1655 | lua_assert(base == ci->func + 1); |
1657 | } | 1656 | } |
1658 | if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) { /* Lua function? */ | 1657 | if (luaD_precall(L, ra, LUA_MULTRET, delta + 1)) /* Lua function? */ |
1659 | ci->callstatus |= CIST_TAIL; | ||
1660 | goto startfunc; /* execute the callee */ | 1658 | goto startfunc; /* execute the callee */ |
1661 | } | ||
1662 | else { /* C function */ | 1659 | else { /* C function */ |
1663 | updatetrap(ci); | 1660 | updatetrap(ci); |
1664 | updatestack(ci); /* stack may have been relocated */ | ||
1665 | ci->func -= delta; /* restore 'func' (if vararg) */ | ||
1666 | luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ | ||
1667 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ | ||
1668 | goto ret; /* caller returns after the tail call */ | 1661 | goto ret; /* caller returns after the tail call */ |
1669 | } | 1662 | } |
1670 | } | 1663 | } |