aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-03-09 11:42:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-03-09 11:42:45 -0300
commit511d53a826760dd11cd82947184583e2d094e2d2 (patch)
tree60dc1a2da1198fc7c9e058b794b03c757e0c48f7 /lapi.c
parentf5df7f91f70234850484d26caf24e71e001e5304 (diff)
downloadlua-511d53a826760dd11cd82947184583e2d094e2d2.tar.gz
lua-511d53a826760dd11cd82947184583e2d094e2d2.tar.bz2
lua-511d53a826760dd11cd82947184583e2d094e2d2.zip
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.
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c15
1 files changed, 8 insertions, 7 deletions
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) {
173 173
174LUA_API void lua_settop (lua_State *L, int idx) { 174LUA_API void lua_settop (lua_State *L, int idx) {
175 CallInfo *ci; 175 CallInfo *ci;
176 StkId func; 176 StkId func, newtop;
177 ptrdiff_t diff; /* difference for new top */ 177 ptrdiff_t diff; /* difference for new top */
178 lua_lock(L); 178 lua_lock(L);
179 ci = L->ci; 179 ci = L->ci;
@@ -188,12 +188,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
188 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); 188 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
189 diff = idx + 1; /* will "subtract" index (as it is negative) */ 189 diff = idx + 1; /* will "subtract" index (as it is negative) */
190 } 190 }
191#if defined(LUA_COMPAT_5_4_0) 191 api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot");
192 if (diff < 0 && hastocloseCfunc(ci->nresults)) 192 newtop = L->top + diff;
193 luaF_close(L, L->top + diff, CLOSEKTOP, 0); 193 if (diff < 0 && L->tbclist >= newtop) {
194#endif 194 lua_assert(hastocloseCfunc(ci->nresults));
195 api_check(L, L->tbclist < L->top + diff, "cannot pop an unclosed slot"); 195 luaF_close(L, newtop, CLOSEKTOP, 0);
196 L->top += diff; 196 }
197 L->top = newtop; /* correct top only after closing any upvalue */
197 lua_unlock(L); 198 lua_unlock(L);
198} 199}
199 200