Closing methods should not interfere with returning values
A closing method cannot be called in its own stack slot, as there may be returning values in the stack after that slot, and the call would corrupt those values. Instead, the closing method must be copied to the top of the stack to be called. Moreover, even when a function returns no value, its return istruction still has to have its position (which will set the stack top) after the local variables, otherwise a closing method might corrupt another not-yet-called closing method.
This commit is contained in:
6
lvm.c
6
lvm.c
@@ -1452,7 +1452,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CLOSE) {
|
||||
luaF_close(L, ra, LUA_OK);
|
||||
L->top = ra + 1; /* everything is free after this slot */
|
||||
ProtectNT(luaF_close(L, ra, LUA_OK));
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_TBC) {
|
||||
@@ -1619,13 +1620,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
n = cast_int(L->top - ra); /* get what is available */
|
||||
else
|
||||
L->top = ra + n; /* set call for 'luaD_poscall' */
|
||||
savepc(ci);
|
||||
if (TESTARG_k(i)) {
|
||||
int nparams1 = GETARG_C(i);
|
||||
if (nparams1) /* vararg function? */
|
||||
ci->func -= ci->u.l.nextraargs + nparams1;
|
||||
luaF_close(L, base, LUA_OK); /* there may be open upvalues */
|
||||
}
|
||||
halfProtect(luaD_poscall(L, ci, n));
|
||||
luaD_poscall(L, ci, n);
|
||||
return;
|
||||
}
|
||||
vmcase(OP_RETURN0) {
|
||||
|
||||
Reference in New Issue
Block a user