-
Notifications
You must be signed in to change notification settings - Fork 931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IRSLOAD_READONLY of FORL_STEP slot can leak to other slots #1123
Comments
If IRSLOAD_READONLY loads can be referenced from "non-home" positions, then diff --git a/src/lj_record.c b/src/lj_record.c
index b7af589697..5d152544a8 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -280,19 +280,25 @@ typedef enum {
LOOPEV_ENTER /* Loop is entered. */
} LoopEvent;
-/* Canonicalize slots: convert integers to numbers. */
+/* Canonicalize slots: convert integers to numbers in latest snapshot. */
static void canonicalize_slots(jit_State *J)
{
- BCReg s;
- if (LJ_DUALNUM) return;
- for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
- TRef tr = J->slot[s];
- if (tref_isinteger(tr) && !(tr & TREF_KEYINDEX)) {
- IRIns *ir = IR(tref_ref(tr));
- if (!(ir->o == IR_SLOAD && (ir->op2 & (IRSLOAD_READONLY))))
- J->slot[s] = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
+ SnapShot *snap = &J->cur.snap[J->cur.nsnap] - 1;
+ SnapEntry *map = &J->cur.snapmap[snap->mapofs];
+ MSize n, nent = snap->nent;
+ for (n = 0; n < nent; n++) {
+ SnapEntry sn = map[n];
+ if (!(sn & (SNAP_NORESTORE | SNAP_SOFTFPNUM | SNAP_KEYINDEX))) {
+ if (tref_isinteger(J->slot[snap_slot(sn)])) {
+ TRef tr = emitir(IRTN(IR_CONV), snap_ref(sn), IRCONV_NUM_INT);
+ sn = SNAP_TR(snap_slot(sn), tr);
+ if (LJ_SOFTFP32)
+ sn |= SNAP_SOFTFPNUM;
+ map[n] = sn;
+ }
}
}
+ snap->ref = (IRRef1)J->cur.nins; /* To include any new IR_CONVs. */
}
/* Stop recording. */
@@ -305,19 +311,19 @@ void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
lj_trace_end(J);
J->cur.linktype = (uint8_t)linktype;
J->cur.link = (uint16_t)lnk;
+ /* Note: all loop ops must set J->pc to the following instruction! */
+ lj_snap_add(J); /* Add loop snapshot. */
+ J->needsnap = 0;
+ J->mergesnap = 1; /* In case recording continues. */
/* Looping back at the same stack level? */
- if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
+ if (J->cur.link == J->cur.traceno && J->framedepth + J->retdepth == 0) {
if ((J->flags & JIT_F_OPT_LOOP)) /* Shall we try to create a loop? */
- goto nocanon; /* Do not canonicalize or we lose the narrowing. */
+ return; /* Do not canonicalize or we lose the narrowing. */
if (J->cur.root) /* Otherwise ensure we always link to the root trace. */
J->cur.link = J->cur.root;
}
- canonicalize_slots(J);
-nocanon:
- /* Note: all loop ops must set J->pc to the following instruction! */
- lj_snap_add(J); /* Add loop snapshot. */
- J->needsnap = 0;
- J->mergesnap = 1; /* In case recording continues. */
+ if (!LJ_DUALNUM)
+ canonicalize_slots(J);
}
/* Search bytecode backwards for a int/num constant slot initializer. */ (At this point, IRSLOAD_READONLY becomes a no-op unless IRSLOAD_PARENT is also present) |
Occurrences of
IRSLOAD_READONLY
are limited to slots that are not visible to the Lua-level programmer:Of these cases, the load of a FORL_STEP variable can be plucked out of the IR via fold rules, and then made visible to the Lua-level programmer. It can then be copied to another slot at a lower slot number than the original FORL_STEP variable. This causes no problems for
snapshot_slots
, as it only respectsIRSLOAD_READONLY
whenir->op1 == s
, but it causes problems forlj_snap_replay
, as it'll end up forming an SLOAD of the copy (rather than the original) withIRSLOAD_PARENT|IRSLOAD_READONLY
, and that causes problems forsnapshot_slots
, as it'll mark the copy (rather than the original) withSNAP_NORESTORE
.An example of this is:
Possibly there's a solution in the area of performing the IRSLOAD_READONLY SLOAD against the slot number which had SNAP_NORESTORE:
(The assumption in
lj_snap_regspmap
that SLOADs occur in order of increasing slot number is mildly unpleasant. There's a major shakeup that would remove the need for it: change the SLOAD fields such that the low 8 bits of op1 are the slot number, the high 7 bits of op1 are flags, and for parent loads op2 contains the ref in the parent. One could then also eliminate IR_PVAL and instead represent it as a SLOAD from slot 255.)The text was updated successfully, but these errors were encountered: