diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-08-18 12:05:06 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-08-18 12:05:06 -0300 |
| commit | 91673a8ec0ae55e188a790bd2dfdc99246adf20e (patch) | |
| tree | 4370ab4d6fa5127cc6bb44a1dfa62ea5eca8ff88 | |
| parent | 41871f1803770305f182f56cbd22a336c5236a19 (diff) | |
| download | lua-91673a8ec0ae55e188a790bd2dfdc99246adf20e.tar.gz lua-91673a8ec0ae55e188a790bd2dfdc99246adf20e.tar.bz2 lua-91673a8ec0ae55e188a790bd2dfdc99246adf20e.zip | |
'luaD_tryfuncTM' checks stack space by itself
| -rw-r--r-- | ldo.c | 7 | ||||
| -rw-r--r-- | ldo.h | 2 | ||||
| -rw-r--r-- | lvm.c | 11 |
3 files changed, 11 insertions, 9 deletions
| @@ -387,15 +387,17 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) { | |||
| 387 | ** stack, below original 'func', so that 'luaD_precall' can call it. Raise | 387 | ** stack, below original 'func', so that 'luaD_precall' can call it. Raise |
| 388 | ** an error if there is no '__call' metafield. | 388 | ** an error if there is no '__call' metafield. |
| 389 | */ | 389 | */ |
| 390 | void luaD_tryfuncTM (lua_State *L, StkId func) { | 390 | StkId luaD_tryfuncTM (lua_State *L, StkId func) { |
| 391 | const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); | 391 | const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); |
| 392 | StkId p; | 392 | StkId p; |
| 393 | checkstackGCp(L, 1, func); /* space for metamethod */ | ||
| 393 | if (l_unlikely(ttisnil(tm))) | 394 | if (l_unlikely(ttisnil(tm))) |
| 394 | luaG_callerror(L, s2v(func)); /* nothing to call */ | 395 | luaG_callerror(L, s2v(func)); /* nothing to call */ |
| 395 | for (p = L->top; p > func; p--) /* open space for metamethod */ | 396 | for (p = L->top; p > func; p--) /* open space for metamethod */ |
| 396 | setobjs2s(L, p, p-1); | 397 | setobjs2s(L, p, p-1); |
| 397 | L->top++; /* stack space pre-allocated by the caller */ | 398 | L->top++; /* stack space pre-allocated by the caller */ |
| 398 | setobj2s(L, func, tm); /* metamethod is the new function to be called */ | 399 | setobj2s(L, func, tm); /* metamethod is the new function to be called */ |
| 400 | return func; | ||
| 399 | } | 401 | } |
| 400 | 402 | ||
| 401 | 403 | ||
| @@ -558,8 +560,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { | |||
| 558 | return ci; | 560 | return ci; |
| 559 | } | 561 | } |
| 560 | default: { /* not a function */ | 562 | default: { /* not a function */ |
| 561 | checkstackGCp(L, 1, func); /* space for metamethod */ | 563 | func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ |
| 562 | luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ | ||
| 563 | goto retry; /* try again with metamethod */ | 564 | goto retry; /* try again with metamethod */ |
| 564 | } | 565 | } |
| 565 | } | 566 | } |
| @@ -62,7 +62,7 @@ LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); | |||
| 62 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); | 62 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); |
| 63 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | 63 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); |
| 64 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | 64 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); |
| 65 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); | 65 | LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func); |
| 66 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); | 66 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); |
| 67 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | 67 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 68 | ptrdiff_t oldtop, ptrdiff_t ef); | 68 | ptrdiff_t oldtop, ptrdiff_t ef); |
| @@ -1657,9 +1657,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1657 | lua_assert(base == ci->func + 1); | 1657 | lua_assert(base == ci->func + 1); |
| 1658 | } | 1658 | } |
| 1659 | while (!ttisfunction(s2v(ra))) { /* not a function? */ | 1659 | while (!ttisfunction(s2v(ra))) { /* not a function? */ |
| 1660 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ | 1660 | ra = luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ |
| 1661 | b++; /* there is now one extra argument */ | 1661 | b++; /* there is now one extra argument */ |
| 1662 | checkstackGCp(L, 1, ra); | ||
| 1663 | } | 1662 | } |
| 1664 | if (!ttisLclosure(s2v(ra))) { /* C function? */ | 1663 | if (!ttisLclosure(s2v(ra))) { /* C function? */ |
| 1665 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ | 1664 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ |
| @@ -1670,9 +1669,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1670 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ | 1669 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ |
| 1671 | goto ret; /* caller returns after the tail call */ | 1670 | goto ret; /* caller returns after the tail call */ |
| 1672 | } | 1671 | } |
| 1673 | ci->func -= delta; /* restore 'func' (if vararg) */ | 1672 | else { /* Lua function */ |
| 1674 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | 1673 | ci->func -= delta; /* restore 'func' (if vararg) */ |
| 1675 | goto startfunc; /* execute the callee */ | 1674 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ |
| 1675 | goto startfunc; /* execute the callee */ | ||
| 1676 | } | ||
| 1676 | } | 1677 | } |
| 1677 | vmcase(OP_RETURN) { | 1678 | vmcase(OP_RETURN) { |
| 1678 | int n = GETARG_B(i) - 1; /* number of results */ | 1679 | int n = GETARG_B(i) - 1; /* number of results */ |
