From 511d53a826760dd11cd82947184583e2d094e2d2 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 9 Mar 2021 11:42:45 -0300 Subject: lua_settop/lua_pop closes to-be-closed variables The existence of 'lua_closeslot' is no reason for lua_pop not to close to-be-closed variables too. It is too error-prone for lua_pop not to close tbc variables being popped from the stack. --- lapi.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lapi.c') diff --git a/lapi.c b/lapi.c index a9cf2fdb..f8f70cd0 100644 --- a/lapi.c +++ b/lapi.c @@ -173,7 +173,7 @@ LUA_API int lua_gettop (lua_State *L) { LUA_API void lua_settop (lua_State *L, int idx) { CallInfo *ci; - StkId func; + StkId func, newtop; ptrdiff_t diff; /* difference for new top */ lua_lock(L); ci = L->ci; @@ -188,12 +188,13 @@ LUA_API void lua_settop (lua_State *L, int idx) { api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); diff = idx + 1; /* will "subtract" index (as it is negative) */ } -#if defined(LUA_COMPAT_5_4_0) - if (diff < 0 && hastocloseCfunc(ci->nresults)) - luaF_close(L, L->top + diff, CLOSEKTOP, 0); -#endif - api_check(L, L->tbclist < L->top + diff, "cannot pop an unclosed slot"); - L->top += diff; + api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot"); + newtop = L->top + diff; + if (diff < 0 && L->tbclist >= newtop) { + lua_assert(hastocloseCfunc(ci->nresults)); + luaF_close(L, newtop, CLOSEKTOP, 0); + } + L->top = newtop; /* correct top only after closing any upvalue */ lua_unlock(L); } -- cgit v1.2.3-55-g6feb