Handle table unsinking in the presence of IRFL_TAB_NOMM.

Reported by Sergey Kaplun. #1052
This commit is contained in:
Mike Pall 2023-08-28 22:15:42 +02:00
parent 6a3111a57f
commit 0ef51b495f

View File

@ -796,17 +796,26 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex,
lj_tab_dup(J->L, ir_ktab(&T->ir[ir->op1]));
settabV(J->L, o, t);
irlast = &T->ir[T->snap[snapno].ref];
for (irs = ir+1; irs < irlast; irs++)
for (irs = ir+1; irs < irlast; irs++) {
if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) {
IRIns *irk = &T->ir[irs->op1];
TValue tmp, *val;
lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE ||
irs->o == IR_FSTORE);
if (irk->o == IR_FREF) {
lua_assert(irk->op2 == IRFL_TAB_META);
switch (irk->op2) {
case IRFL_TAB_META:
snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp);
/* NOBARRIER: The table is new (marked white). */
setgcref(t->metatable, obj2gco(tabV(&tmp)));
break;
case IRFL_TAB_NOMM:
/* Negative metamethod cache invalidated by lj_tab_set() below. */
break;
default:
lua_assert(0);
break;
}
} else {
irk = &T->ir[irk->op2];
if (irk->o == IR_KSLOT) irk = &T->ir[irk->op1];
@ -822,6 +831,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex,
}
}
}
}
/* Restore interpreter state from exit state with the help of a snapshot. */
const BCIns *lj_snap_restore(jit_State *J, void *exptr)