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 | ||
