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 */ |