diff options
author | Mike Pall <mike> | 2023-11-05 16:34:46 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2023-11-05 16:34:46 +0100 |
commit | 07b3cd3cf9b57a3801a1ebc48144767e31671f21 (patch) | |
tree | f8d8eeed931dc75a7f3853271c14e087f76731ec /src/lj_asm_x86.h | |
parent | 0afa1676b2d2aabf1f3101a2692eb0f1e291076a (diff) | |
download | luajit-07b3cd3cf9b57a3801a1ebc48144767e31671f21.tar.gz luajit-07b3cd3cf9b57a3801a1ebc48144767e31671f21.tar.bz2 luajit-07b3cd3cf9b57a3801a1ebc48144767e31671f21.zip |
Check for upvalue state transition in IR_UREFO.
Thanks to Peter Cawley. #1085
Diffstat (limited to 'src/lj_asm_x86.h')
-rw-r--r-- | src/lj_asm_x86.h | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index c92de3d8..0e0b28a4 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -1373,24 +1373,31 @@ static void asm_hrefk(ASMState *as, IRIns *ir) | |||
1373 | static void asm_uref(ASMState *as, IRIns *ir) | 1373 | static void asm_uref(ASMState *as, IRIns *ir) |
1374 | { | 1374 | { |
1375 | Reg dest = ra_dest(as, ir, RSET_GPR); | 1375 | Reg dest = ra_dest(as, ir, RSET_GPR); |
1376 | if (irref_isk(ir->op1)) { | 1376 | int guarded = (irt_t(ir->t) & (IRT_GUARD|IRT_TYPE)) == (IRT_GUARD|IRT_PGC); |
1377 | if (irref_isk(ir->op1) && !guarded) { | ||
1377 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 1378 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
1378 | MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; | 1379 | MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; |
1379 | emit_rma(as, XO_MOV, dest|REX_GC64, v); | 1380 | emit_rma(as, XO_MOV, dest|REX_GC64, v); |
1380 | } else { | 1381 | } else { |
1381 | Reg uv = ra_scratch(as, RSET_GPR); | 1382 | Reg uv = ra_scratch(as, RSET_GPR); |
1382 | Reg func = ra_alloc1(as, ir->op1, RSET_GPR); | 1383 | if (ir->o == IR_UREFC) |
1383 | if (ir->o == IR_UREFC) { | ||
1384 | emit_rmro(as, XO_LEA, dest|REX_GC64, uv, offsetof(GCupval, tv)); | 1384 | emit_rmro(as, XO_LEA, dest|REX_GC64, uv, offsetof(GCupval, tv)); |
1385 | asm_guardcc(as, CC_NE); | 1385 | else |
1386 | emit_i8(as, 1); | 1386 | emit_rmro(as, XO_MOV, dest|REX_GC64, uv, offsetof(GCupval, v)); |
1387 | if (guarded) { | ||
1388 | asm_guardcc(as, ir->o == IR_UREFC ? CC_E : CC_NE); | ||
1389 | emit_i8(as, 0); | ||
1387 | emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed)); | 1390 | emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed)); |
1391 | } | ||
1392 | if (irref_isk(ir->op1)) { | ||
1393 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | ||
1394 | GCobj *o = gcref(fn->l.uvptr[(ir->op2 >> 8)]); | ||
1395 | emit_loada(as, uv, o); | ||
1388 | } else { | 1396 | } else { |
1389 | emit_rmro(as, XO_MOV, dest|REX_GC64, uv, offsetof(GCupval, v)); | 1397 | emit_rmro(as, XO_MOV, uv|REX_GC64, ra_alloc1(as, ir->op1, RSET_GPR), |
1398 | (int32_t)offsetof(GCfuncL, uvptr) + | ||
1399 | (int32_t)sizeof(MRef) * (int32_t)(ir->op2 >> 8)); | ||
1390 | } | 1400 | } |
1391 | emit_rmro(as, XO_MOV, uv|REX_GC64, func, | ||
1392 | (int32_t)offsetof(GCfuncL, uvptr) + | ||
1393 | (int32_t)sizeof(MRef) * (int32_t)(ir->op2 >> 8)); | ||
1394 | } | 1401 | } |
1395 | } | 1402 | } |
1396 | 1403 | ||