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 | |
| parent | 5837c2a2fb1ba66510c9100a296966020f1610a3 (diff) | |
| download | luajit-37e1e70313367d0264be9a2b9e563a8a94745303.tar.gz luajit-37e1e70313367d0264be9a2b9e563a8a94745303.tar.bz2 luajit-37e1e70313367d0264be9a2b9e563a8a94745303.zip | |
Add guard for obscure aliasing between open upvalues and SSA slots.
Thanks to Peter Cawley.
| -rw-r--r-- | doc/status.html | 6 | ||||
| -rw-r--r-- | src/lj_asm_arm.h | 1 | ||||
| -rw-r--r-- | src/lj_asm_mips.h | 1 | ||||
| -rw-r--r-- | src/lj_asm_ppc.h | 1 | ||||
| -rw-r--r-- | src/lj_asm_x86.h | 1 | ||||
| -rw-r--r-- | src/lj_record.c | 10 |
6 files changed, 8 insertions, 12 deletions
diff --git a/doc/status.html b/doc/status.html index c305f47a..b3524397 100644 --- a/doc/status.html +++ b/doc/status.html | |||
| @@ -89,12 +89,6 @@ hooks for non-Lua functions) and shows slightly different behavior | |||
| 89 | in LuaJIT (no per-coroutine hooks, no tail call counting). | 89 | in LuaJIT (no per-coroutine hooks, no tail call counting). |
| 90 | </li> | 90 | </li> |
| 91 | <li> | 91 | <li> |
| 92 | Some checks are missing in the JIT-compiled code for obscure situations | ||
| 93 | with <b>open upvalues aliasing</b> one of the SSA slots later on (or | ||
| 94 | vice versa). Bonus points, if you can find a real world test case for | ||
| 95 | this. | ||
| 96 | </li> | ||
| 97 | <li> | ||
| 98 | Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not | 92 | Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not |
| 99 | handled correctly. The error may fall through an on-trace | 93 | handled correctly. The error may fall through an on-trace |
| 100 | <tt>pcall</tt> or it may be passed on to the function set with | 94 | <tt>pcall</tt> 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 ff688746..a722a11f 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
| @@ -976,7 +976,6 @@ static void asm_newref(ASMState *as, IRIns *ir) | |||
| 976 | 976 | ||
| 977 | static void asm_uref(ASMState *as, IRIns *ir) | 977 | static void asm_uref(ASMState *as, IRIns *ir) |
| 978 | { | 978 | { |
| 979 | /* NYI: Check that UREFO is still open and not aliasing a slot. */ | ||
| 980 | Reg dest = ra_dest(as, ir, RSET_GPR); | 979 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 981 | if (irref_isk(ir->op1)) { | 980 | if (irref_isk(ir->op1)) { |
| 982 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 981 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index 4045fe80..66953aac 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
| @@ -793,7 +793,6 @@ static void asm_newref(ASMState *as, IRIns *ir) | |||
| 793 | 793 | ||
| 794 | static void asm_uref(ASMState *as, IRIns *ir) | 794 | static void asm_uref(ASMState *as, IRIns *ir) |
| 795 | { | 795 | { |
| 796 | /* NYI: Check that UREFO is still open and not aliasing a slot. */ | ||
| 797 | Reg dest = ra_dest(as, ir, RSET_GPR); | 796 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 798 | if (irref_isk(ir->op1)) { | 797 | if (irref_isk(ir->op1)) { |
| 799 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 798 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index e8f3d08b..e1b0c980 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
| @@ -789,7 +789,6 @@ static void asm_newref(ASMState *as, IRIns *ir) | |||
| 789 | 789 | ||
| 790 | static void asm_uref(ASMState *as, IRIns *ir) | 790 | static void asm_uref(ASMState *as, IRIns *ir) |
| 791 | { | 791 | { |
| 792 | /* NYI: Check that UREFO is still open and not aliasing a slot. */ | ||
| 793 | Reg dest = ra_dest(as, ir, RSET_GPR); | 792 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 794 | if (irref_isk(ir->op1)) { | 793 | if (irref_isk(ir->op1)) { |
| 795 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 794 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 02918e23..db3e49f8 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
| @@ -1215,7 +1215,6 @@ static void asm_newref(ASMState *as, IRIns *ir) | |||
| 1215 | 1215 | ||
| 1216 | static void asm_uref(ASMState *as, IRIns *ir) | 1216 | static void asm_uref(ASMState *as, IRIns *ir) |
| 1217 | { | 1217 | { |
| 1218 | /* NYI: Check that UREFO is still open and not aliasing a slot. */ | ||
| 1219 | Reg dest = ra_dest(as, ir, RSET_GPR); | 1218 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 1220 | if (irref_isk(ir->op1)) { | 1219 | if (irref_isk(ir->op1)) { |
| 1221 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 1220 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
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: | |||
| 1343 | /* Note: this effectively limits LJ_MAX_UPVAL to 127. */ | 1343 | /* Note: this effectively limits LJ_MAX_UPVAL to 127. */ |
| 1344 | uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff); | 1344 | uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff); |
| 1345 | if (!uvp->closed) { | 1345 | if (!uvp->closed) { |
| 1346 | uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv)); | ||
| 1346 | /* In current stack? */ | 1347 | /* In current stack? */ |
| 1347 | if (uvval(uvp) >= tvref(J->L->stack) && | 1348 | if (uvval(uvp) >= tvref(J->L->stack) && |
| 1348 | uvval(uvp) < tvref(J->L->maxstack)) { | 1349 | uvval(uvp) < tvref(J->L->maxstack)) { |
| 1349 | int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot)); | 1350 | int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot)); |
| 1350 | if (slot >= 0) { /* Aliases an SSA slot? */ | 1351 | if (slot >= 0) { /* Aliases an SSA slot? */ |
| 1352 | emitir(IRTG(IR_EQ, IRT_P32), | ||
| 1353 | REF_BASE, | ||
| 1354 | emitir(IRT(IR_ADD, IRT_P32), uref, | ||
| 1355 | lj_ir_kint(J, (slot - 1) * -8))); | ||
| 1351 | slot -= (int32_t)J->baseslot; /* Note: slot number may be negative! */ | 1356 | slot -= (int32_t)J->baseslot; /* Note: slot number may be negative! */ |
| 1352 | /* NYI: add IR to guard that it's still aliasing the same slot. */ | ||
| 1353 | if (val == 0) { | 1357 | if (val == 0) { |
| 1354 | return getslot(J, slot); | 1358 | return getslot(J, slot); |
| 1355 | } else { | 1359 | } else { |
| @@ -1359,7 +1363,9 @@ noconstify: | |||
| 1359 | } | 1363 | } |
| 1360 | } | 1364 | } |
| 1361 | } | 1365 | } |
| 1362 | uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv)); | 1366 | emitir(IRTG(IR_UGT, IRT_P32), |
| 1367 | emitir(IRT(IR_SUB, IRT_P32), uref, REF_BASE), | ||
| 1368 | lj_ir_kint(J, (J->baseslot + J->maxslot) * 8)); | ||
| 1363 | } else { | 1369 | } else { |
| 1364 | needbarrier = 1; | 1370 | needbarrier = 1; |
| 1365 | uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv)); | 1371 | uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv)); |
