mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Add guard for obscure aliasing between open upvalues and SSA slots.
Thanks to Peter Cawley.
This commit is contained in:
parent
5837c2a2fb
commit
37e1e70313
@ -89,12 +89,6 @@ hooks for non-Lua functions) and shows slightly different behavior
|
|||||||
in LuaJIT (no per-coroutine hooks, no tail call counting).
|
in LuaJIT (no per-coroutine hooks, no tail call counting).
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Some checks are missing in the JIT-compiled code for obscure situations
|
|
||||||
with <b>open upvalues aliasing</b> one of the SSA slots later on (or
|
|
||||||
vice versa). Bonus points, if you can find a real world test case for
|
|
||||||
this.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not
|
Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not
|
||||||
handled correctly. The error may fall through an on-trace
|
handled correctly. The error may fall through an on-trace
|
||||||
<tt>pcall</tt> or it may be passed on to the function set with
|
<tt>pcall</tt> or it may be passed on to the function set with
|
||||||
|
@ -976,7 +976,6 @@ static void asm_newref(ASMState *as, IRIns *ir)
|
|||||||
|
|
||||||
static void asm_uref(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);
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||||
if (irref_isk(ir->op1)) {
|
if (irref_isk(ir->op1)) {
|
||||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||||
|
@ -793,7 +793,6 @@ static void asm_newref(ASMState *as, IRIns *ir)
|
|||||||
|
|
||||||
static void asm_uref(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);
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||||
if (irref_isk(ir->op1)) {
|
if (irref_isk(ir->op1)) {
|
||||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||||
|
@ -789,7 +789,6 @@ static void asm_newref(ASMState *as, IRIns *ir)
|
|||||||
|
|
||||||
static void asm_uref(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);
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||||
if (irref_isk(ir->op1)) {
|
if (irref_isk(ir->op1)) {
|
||||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||||
|
@ -1215,7 +1215,6 @@ static void asm_newref(ASMState *as, IRIns *ir)
|
|||||||
|
|
||||||
static void asm_uref(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);
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||||
if (irref_isk(ir->op1)) {
|
if (irref_isk(ir->op1)) {
|
||||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||||
|
@ -1343,13 +1343,17 @@ noconstify:
|
|||||||
/* Note: this effectively limits LJ_MAX_UPVAL to 127. */
|
/* Note: this effectively limits LJ_MAX_UPVAL to 127. */
|
||||||
uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
|
uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
|
||||||
if (!uvp->closed) {
|
if (!uvp->closed) {
|
||||||
|
uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv));
|
||||||
/* In current stack? */
|
/* In current stack? */
|
||||||
if (uvval(uvp) >= tvref(J->L->stack) &&
|
if (uvval(uvp) >= tvref(J->L->stack) &&
|
||||||
uvval(uvp) < tvref(J->L->maxstack)) {
|
uvval(uvp) < tvref(J->L->maxstack)) {
|
||||||
int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
|
int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
|
||||||
if (slot >= 0) { /* Aliases an SSA slot? */
|
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! */
|
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) {
|
if (val == 0) {
|
||||||
return getslot(J, slot);
|
return getslot(J, slot);
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
needbarrier = 1;
|
needbarrier = 1;
|
||||||
uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv));
|
uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv));
|
||||||
|
Loading…
Reference in New Issue
Block a user