diff options
author | Mike Pall <mike> | 2023-08-28 22:15:42 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2023-08-28 22:15:42 +0200 |
commit | 0ef51b495f9497aac77b41eb3d837c9c38b9424b (patch) | |
tree | f5d3071daf62fdfa6c1b7e26ac50d9a3be787c41 /src | |
parent | 6a3111a57f817cb00ef2ab6f2553cd887ec36462 (diff) | |
download | luajit-0ef51b495f9497aac77b41eb3d837c9c38b9424b.tar.gz luajit-0ef51b495f9497aac77b41eb3d837c9c38b9424b.tar.bz2 luajit-0ef51b495f9497aac77b41eb3d837c9c38b9424b.zip |
Handle table unsinking in the presence of IRFL_TAB_NOMM.
Reported by Sergey Kaplun. #1052
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_snap.c | 20 |
1 files changed, 15 insertions, 5 deletions
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, | |||
796 | lj_tab_dup(J->L, ir_ktab(&T->ir[ir->op1])); | 796 | lj_tab_dup(J->L, ir_ktab(&T->ir[ir->op1])); |
797 | settabV(J->L, o, t); | 797 | settabV(J->L, o, t); |
798 | irlast = &T->ir[T->snap[snapno].ref]; | 798 | irlast = &T->ir[T->snap[snapno].ref]; |
799 | for (irs = ir+1; irs < irlast; irs++) | 799 | for (irs = ir+1; irs < irlast; irs++) { |
800 | if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { | 800 | if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { |
801 | IRIns *irk = &T->ir[irs->op1]; | 801 | IRIns *irk = &T->ir[irs->op1]; |
802 | TValue tmp, *val; | 802 | TValue tmp, *val; |
803 | lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE || | 803 | lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE || |
804 | irs->o == IR_FSTORE); | 804 | irs->o == IR_FSTORE); |
805 | if (irk->o == IR_FREF) { | 805 | if (irk->o == IR_FREF) { |
806 | lua_assert(irk->op2 == IRFL_TAB_META); | 806 | switch (irk->op2) { |
807 | snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp); | 807 | case IRFL_TAB_META: |
808 | /* NOBARRIER: The table is new (marked white). */ | 808 | snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp); |
809 | setgcref(t->metatable, obj2gco(tabV(&tmp))); | 809 | /* NOBARRIER: The table is new (marked white). */ |
810 | setgcref(t->metatable, obj2gco(tabV(&tmp))); | ||
811 | break; | ||
812 | case IRFL_TAB_NOMM: | ||
813 | /* Negative metamethod cache invalidated by lj_tab_set() below. */ | ||
814 | break; | ||
815 | default: | ||
816 | lua_assert(0); | ||
817 | break; | ||
818 | } | ||
810 | } else { | 819 | } else { |
811 | irk = &T->ir[irk->op2]; | 820 | irk = &T->ir[irk->op2]; |
812 | if (irk->o == IR_KSLOT) irk = &T->ir[irk->op1]; | 821 | 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, | |||
820 | } | 829 | } |
821 | } | 830 | } |
822 | } | 831 | } |
832 | } | ||
823 | } | 833 | } |
824 | } | 834 | } |
825 | 835 | ||