diff options
author | Mike Pall <mike> | 2016-05-20 20:24:06 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2016-05-20 20:24:06 +0200 |
commit | 37e1e70313367d0264be9a2b9e563a8a94745303 (patch) | |
tree | d923eb98312da45aefac76176eddf49e7955b3a6 /src/lj_record.c | |
parent | 5837c2a2fb1ba66510c9100a296966020f1610a3 (diff) | |
download | luajit2-37e1e70313367d0264be9a2b9e563a8a94745303.tar.gz |
Add guard for obscure aliasing between open upvalues and SSA slots.
Thanks to Peter Cawley.
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index ff7825ee..44b3667f 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1343,13 +1343,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) * -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 { @@ -1359,7 +1363,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)); |