mirror of https://github.com/rusefi/lua.git
Some bugs with stack reallocation by 'luaF_close'
(Long time without testing with '-DHARDSTACKTESTS'...) With the introduction of to-be-closed variables, calls to 'luaF_close' can move the stack, but some call sites where keeping pointers to the stack without correcting them.
This commit is contained in:
parent
84e32ad2eb
commit
7e63d3da02
9
ldo.c
9
ldo.c
|
@ -383,8 +383,10 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
|||
wanted = nres; /* we want all results */
|
||||
break;
|
||||
default: /* multiple results (or to-be-closed variables) */
|
||||
if (hastocloseCfunc(wanted)) {
|
||||
luaF_close(L, res, LUA_OK);
|
||||
if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
|
||||
ptrdiff_t savedres = savestack(L, res);
|
||||
luaF_close(L, res, LUA_OK); /* may change the stack */
|
||||
res = restorestack(L, savedres);
|
||||
wanted = codeNresults(wanted); /* correct value */
|
||||
if (wanted == LUA_MULTRET)
|
||||
wanted = nres;
|
||||
|
@ -590,7 +592,8 @@ static int recover (lua_State *L, int status) {
|
|||
if (ci == NULL) return 0; /* no recovery point */
|
||||
/* "finish" luaD_pcall */
|
||||
oldtop = restorestack(L, ci->u2.funcidx);
|
||||
luaF_close(L, oldtop, status);
|
||||
luaF_close(L, oldtop, status); /* may change the stack */
|
||||
oldtop = restorestack(L, ci->u2.funcidx);
|
||||
luaD_seterrorobj(L, status, oldtop);
|
||||
L->ci = ci;
|
||||
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i));
|
||||
|
||||
|
||||
static void *disptab[] = {
|
||||
static void *disptab[NUM_OPCODES] = {
|
||||
|
||||
#if 0
|
||||
** you can update the following list with this command:
|
||||
|
|
2
ltests.c
2
ltests.c
|
@ -142,7 +142,7 @@ void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) {
|
|||
freeblock(mc, block);
|
||||
return NULL;
|
||||
}
|
||||
if (mc->countlimit != ~0UL && size > 0) { /* count limit in use? */
|
||||
if (mc->countlimit != ~0UL && size != oldsize) { /* count limit in use? */
|
||||
if (mc->countlimit == 0)
|
||||
return NULL; /* fake a memory allocation error */
|
||||
mc->countlimit--;
|
||||
|
|
21
lvm.c
21
lvm.c
|
@ -946,6 +946,9 @@ void luaV_finishOp (lua_State *L) {
|
|||
#define updatebase(ci) (base = ci->func + 1)
|
||||
|
||||
|
||||
#define updatestack(ci) { if (trap) { updatebase(ci); ra = RA(i); } }
|
||||
|
||||
|
||||
/*
|
||||
** Execute a jump instruction. The 'updatetrap' allows signals to stop
|
||||
** tight loops. (Without it, the local copy of 'trap' could never change.)
|
||||
|
@ -1557,24 +1560,21 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
L->top = ra + b;
|
||||
else /* previous instruction set top */
|
||||
b = cast_int(L->top - ra);
|
||||
savepc(ci);
|
||||
if (TESTARG_k(i)) {
|
||||
int nparams1 = GETARG_C(i);
|
||||
if (nparams1) /* vararg function? */
|
||||
delta = ci->u.l.nextraargs + nparams1;
|
||||
luaF_close(L, base, LUA_OK); /* close upvalues from current call */
|
||||
/* close upvalues from current call */
|
||||
ProtectNT(luaF_close(L, base, LUA_OK));
|
||||
updatestack(ci);
|
||||
}
|
||||
if (!ttisfunction(s2v(ra))) { /* not a function? */
|
||||
luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
||||
b++; /* there is now one extra argument */
|
||||
}
|
||||
if (!ttisLclosure(s2v(ra))) { /* C function? */
|
||||
luaD_call(L, ra, LUA_MULTRET); /* call it */
|
||||
updatetrap(ci);
|
||||
if (trap) { /* stack may have been relocated */
|
||||
updatebase(ci);
|
||||
ra = RA(i);
|
||||
}
|
||||
ProtectNT(luaD_call(L, ra, LUA_MULTRET)); /* call it */
|
||||
updatestack(ci); /* stack may have been relocated */
|
||||
ci->func -= delta;
|
||||
luaD_poscall(L, ci, cast_int(L->top - ra));
|
||||
return;
|
||||
|
@ -1739,10 +1739,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||
memcpy(ra + 4, ra, 3 * sizeof(*ra));
|
||||
L->top = ra + 4 + 3;
|
||||
Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */
|
||||
if (trap) { /* stack may have changed? */
|
||||
updatebase(ci); /* keep 'base' correct */
|
||||
ra = RA(i); /* keep 'ra' correct for next instruction */
|
||||
}
|
||||
updatestack(ci); /* stack may have changed */
|
||||
i = *(pc++); /* go to next instruction */
|
||||
ra += 2; /* adjust for next instruction */
|
||||
lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
|
||||
|
|
Loading…
Reference in New Issue