From 0ef51b495f9497aac77b41eb3d837c9c38b9424b Mon Sep 17 00:00:00 2001
From: Mike Pall <mike>
Date: Mon, 28 Aug 2023 22:15:42 +0200
Subject: Handle table unsinking in the presence of IRFL_TAB_NOMM.

Reported by Sergey Kaplun. #1052
---
 src/lj_snap.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

(limited to 'src')

diff --git a/src/lj_snap.c b/src/lj_snap.c
index 1ef75e83..a6cd93d4 100644
--- a/src/lj_snap.c
+++ b/src/lj_snap.c
@@ -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,
 	  }
 	}
       }
+    }
   }
 }
 
-- 
cgit v1.2.3-55-g6feb