]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Handle table unsinking in the presence of IRFL_TAB_NOMM.
authorMike Pall <mike>
Mon, 28 Aug 2023 20:15:42 +0000 (22:15 +0200)
committerMike Pall <mike>
Mon, 28 Aug 2023 20:15:42 +0000 (22:15 +0200)
Reported by Sergey Kaplun. #1052

src/lj_snap.c

index 1ef75e8302e9a86ee9e1e2817767b9546cd4686d..a6cd93d49f85178df4ee19ed7f57a89277e057e9 100644 (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);
-         snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp);
-         /* NOBARRIER: The table is new (marked white). */
-         setgcref(t->metatable, obj2gco(tabV(&tmp)));
+         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];
@@ -820,6 +829,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex,
          }
        }
       }
+    }
   }
 }