mirror of https://github.com/rusefi/lua.git
Small bug with stack reallocation
OP_RETURN must update trap before updating stack. (Bug detected with -DHARDSTACKTESTS). Also, in 'luaF_close', do not create a variable with 'uplevel(uv)', as the stack may change and invalidate this value. (This is not a bug, but could become one if 'upl' was used again.)
This commit is contained in:
parent
4eefef07ab
commit
024a6071ca
7
lfunc.c
7
lfunc.c
|
@ -202,13 +202,12 @@ void luaF_unlinkupval (UpVal *uv) {
|
||||||
int luaF_close (lua_State *L, StkId level, int status) {
|
int luaF_close (lua_State *L, StkId level, int status) {
|
||||||
UpVal *uv;
|
UpVal *uv;
|
||||||
while ((uv = L->openupval) != NULL && uplevel(uv) >= level) {
|
while ((uv = L->openupval) != NULL && uplevel(uv) >= level) {
|
||||||
StkId upl = uplevel(uv);
|
|
||||||
TValue *slot = &uv->u.value; /* new position for value */
|
TValue *slot = &uv->u.value; /* new position for value */
|
||||||
lua_assert(upl < L->top);
|
lua_assert(uplevel(uv) < L->top);
|
||||||
if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) {
|
if (uv->tt == LUA_TUPVALTBC && status != NOCLOSINGMETH) {
|
||||||
/* must run closing method */
|
/* must run closing method, which may change the stack */
|
||||||
ptrdiff_t levelrel = savestack(L, level);
|
ptrdiff_t levelrel = savestack(L, level);
|
||||||
status = callclosemth(L, upl, status); /* may change the stack */
|
status = callclosemth(L, uplevel(uv), status);
|
||||||
level = restorestack(L, levelrel);
|
level = restorestack(L, levelrel);
|
||||||
}
|
}
|
||||||
luaF_unlinkupval(uv);
|
luaF_unlinkupval(uv);
|
||||||
|
|
9
lvm.c
9
lvm.c
|
@ -1574,8 +1574,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
savepc(ci); /* some calls here can raise errors */
|
savepc(ci); /* some calls here can raise errors */
|
||||||
if (TESTARG_k(i)) {
|
if (TESTARG_k(i)) {
|
||||||
/* close upvalues from current call; the compiler ensures
|
/* close upvalues from current call; the compiler ensures
|
||||||
that there are no to-be-closed variables here */
|
that there are no to-be-closed variables here, so this
|
||||||
|
call cannot change the stack */
|
||||||
luaF_close(L, base, NOCLOSINGMETH);
|
luaF_close(L, base, NOCLOSINGMETH);
|
||||||
|
lua_assert(base == ci->func + 1);
|
||||||
}
|
}
|
||||||
if (!ttisfunction(s2v(ra))) { /* not a function? */
|
if (!ttisfunction(s2v(ra))) { /* not a function? */
|
||||||
luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||||
|
@ -1602,10 +1604,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
if (n < 0) /* not fixed? */
|
if (n < 0) /* not fixed? */
|
||||||
n = cast_int(L->top - ra); /* get what is available */
|
n = cast_int(L->top - ra); /* get what is available */
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
if (TESTARG_k(i)) {
|
if (TESTARG_k(i)) { /* may there be open upvalues? */
|
||||||
if (L->top < ci->top)
|
if (L->top < ci->top)
|
||||||
L->top = ci->top;
|
L->top = ci->top;
|
||||||
luaF_close(L, base, LUA_OK); /* there may be open upvalues */
|
luaF_close(L, base, LUA_OK);
|
||||||
|
updatetrap(ci);
|
||||||
updatestack(ci);
|
updatestack(ci);
|
||||||
}
|
}
|
||||||
if (nparams1) /* vararg function? */
|
if (nparams1) /* vararg function? */
|
||||||
|
|
Loading…
Reference in New Issue