New API function 'lua_closeslot'

Closing a to-be-closed variable with 'lua_settop' is too restrictive,
as it erases all slots above the variable. Moreover, it adds side
effects to 'lua_settop', which should be a fairly basic function.
This commit is contained in:
Roberto Ierusalimschy
2021-01-11 15:03:01 -03:00
parent ce101dcaf7
commit cc1692515e
6 changed files with 66 additions and 29 deletions

19
lapi.c
View File

@@ -187,9 +187,26 @@ 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);
L->top += diff; /* correct top only after closing any upvalue */
#endif
L->top += diff;
api_check(L, L->openupval == NULL || uplevel(L->openupval) < L->top,
"cannot pop an unclosed slot");
lua_unlock(L);
}
LUA_API void lua_closeslot (lua_State *L, int idx) {
StkId level;
lua_lock(L);
level = index2stack(L, idx);
api_check(L, hastocloseCfunc(L->ci->nresults) && L->openupval != NULL &&
uplevel(L->openupval) == level,
"no variable to close at given level");
luaF_close(L, level, CLOSEKTOP);
setnilvalue(s2v(level));
lua_unlock(L);
}