diff --git a/doc/status.html b/doc/status.html
index 6f57db1b..d10033b0 100644
--- a/doc/status.html
+++ b/doc/status.html
@@ -91,12 +91,6 @@ hooks for non-Lua functions) and shows slightly different behavior
in LuaJIT (no per-coroutine hooks, no tail call counting).
-Some checks are missing in the JIT-compiled code for obscure situations
-with open upvalues aliasing one of the SSA slots later on (or
-vice versa). Bonus points, if you can find a real world test case for
-this.
-
-
Currently some out-of-memory errors from on-trace code are not
handled correctly. The error may fall through an on-trace
pcall or it may be passed on to the function set with
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h
index ff4068a3..c64d59e7 100644
--- a/src/lj_asm_arm.h
+++ b/src/lj_asm_arm.h
@@ -909,7 +909,6 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
static void asm_uref(ASMState *as, IRIns *ir)
{
- /* NYI: Check that UREFO is still open and not aliasing a slot. */
Reg dest = ra_dest(as, ir, RSET_GPR);
if (irref_isk(ir->op1)) {
GCfunc *fn = ir_kfunc(IR(ir->op1));
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h
index 7bd72fda..ecb38c5d 100644
--- a/src/lj_asm_mips.h
+++ b/src/lj_asm_mips.h
@@ -810,7 +810,6 @@ nolo:
static void asm_uref(ASMState *as, IRIns *ir)
{
- /* NYI: Check that UREFO is still open and not aliasing a slot. */
Reg dest = ra_dest(as, ir, RSET_GPR);
if (irref_isk(ir->op1)) {
GCfunc *fn = ir_kfunc(IR(ir->op1));
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h
index 0ebed40f..4cf1649a 100644
--- a/src/lj_asm_ppc.h
+++ b/src/lj_asm_ppc.h
@@ -717,7 +717,6 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
static void asm_uref(ASMState *as, IRIns *ir)
{
- /* NYI: Check that UREFO is still open and not aliasing a slot. */
Reg dest = ra_dest(as, ir, RSET_GPR);
if (irref_isk(ir->op1)) {
GCfunc *fn = ir_kfunc(IR(ir->op1));
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index 66fb4403..6cd3800d 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -1157,7 +1157,6 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
static void asm_uref(ASMState *as, IRIns *ir)
{
- /* NYI: Check that UREFO is still open and not aliasing a slot. */
Reg dest = ra_dest(as, ir, RSET_GPR);
if (irref_isk(ir->op1)) {
GCfunc *fn = ir_kfunc(IR(ir->op1));
diff --git a/src/lj_record.c b/src/lj_record.c
index 8a72b0c9..568b73aa 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -1541,13 +1541,17 @@ noconstify:
/* Note: this effectively limits LJ_MAX_UPVAL to 127. */
uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
if (!uvp->closed) {
+ uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv));
/* In current stack? */
if (uvval(uvp) >= tvref(J->L->stack) &&
uvval(uvp) < tvref(J->L->maxstack)) {
int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
if (slot >= 0) { /* Aliases an SSA slot? */
+ emitir(IRTG(IR_EQ, IRT_P32),
+ REF_BASE,
+ emitir(IRT(IR_ADD, IRT_P32), uref,
+ lj_ir_kint(J, (slot - 1 - LJ_FR2) * -8)));
slot -= (int32_t)J->baseslot; /* Note: slot number may be negative! */
- /* NYI: add IR to guard that it's still aliasing the same slot. */
if (val == 0) {
return getslot(J, slot);
} else {
@@ -1557,7 +1561,9 @@ noconstify:
}
}
}
- uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv));
+ emitir(IRTG(IR_UGT, IRT_P32),
+ emitir(IRT(IR_SUB, IRT_P32), uref, REF_BASE),
+ lj_ir_kint(J, (J->baseslot + J->maxslot) * 8));
} else {
needbarrier = 1;
uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv));