aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_x86.h
diff options
context:
space:
mode:
authorMike Pall <mike>2023-11-05 16:34:46 +0100
committerMike Pall <mike>2023-11-05 16:34:46 +0100
commit07b3cd3cf9b57a3801a1ebc48144767e31671f21 (patch)
treef8d8eeed931dc75a7f3853271c14e087f76731ec /src/lj_asm_x86.h
parent0afa1676b2d2aabf1f3101a2692eb0f1e291076a (diff)
downloadluajit-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.h25
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)
1373static void asm_uref(ASMState *as, IRIns *ir) 1373static 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