Browse Source

Fix snapshot PC when linking to BC_JLOOP that was a BC_RET*.

Reported by Arseny Vakhrushev.
Fix contributed by Peter Cawley.
Mike Pall 4 years ago
parent
commit
5c46f47736
2 changed files with 8 additions and 4 deletions
  1. 5 4
      src/lj_record.c
  2. 3 0
      src/lj_snap.c

+ 5 - 4
src/lj_record.c

@@ -513,10 +513,10 @@ static LoopEvent rec_iterl(jit_State *J, const BCIns iterins)
 }
 }
 
 
 /* Record LOOP/JLOOP. Now, that was easy. */
 /* Record LOOP/JLOOP. Now, that was easy. */
-static LoopEvent rec_loop(jit_State *J, BCReg ra)
+static LoopEvent rec_loop(jit_State *J, BCReg ra, int skip)
 {
 {
   if (ra < J->maxslot) J->maxslot = ra;
   if (ra < J->maxslot) J->maxslot = ra;
-  J->pc++;
+  J->pc += skip;
   return LOOPEV_ENTER;
   return LOOPEV_ENTER;
 }
 }
 
 
@@ -2027,7 +2027,7 @@ void lj_record_ins(jit_State *J)
     rec_loop_interp(J, pc, rec_iterl(J, *pc));
     rec_loop_interp(J, pc, rec_iterl(J, *pc));
     break;
     break;
   case BC_LOOP:
   case BC_LOOP:
-    rec_loop_interp(J, pc, rec_loop(J, ra));
+    rec_loop_interp(J, pc, rec_loop(J, ra, 1));
     break;
     break;
 
 
   case BC_JFORL:
   case BC_JFORL:
@@ -2037,7 +2037,8 @@ void lj_record_ins(jit_State *J)
     rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
     rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
     break;
     break;
   case BC_JLOOP:
   case BC_JLOOP:
-    rec_loop_jit(J, rc, rec_loop(J, ra));
+    rec_loop_jit(J, rc, rec_loop(J, ra,
+				 !bc_isret(bc_op(traceref(J, rc)->startins))));
     break;
     break;
 
 
   case BC_IFORL:
   case BC_IFORL:

+ 3 - 0
src/lj_snap.c

@@ -97,6 +97,9 @@ static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map)
   cTValue *ftop = frame + funcproto(frame_func(frame))->framesize;
   cTValue *ftop = frame + funcproto(frame_func(frame))->framesize;
   MSize f = 0;
   MSize f = 0;
   map[f++] = SNAP_MKPC(J->pc);  /* The current PC is always the first entry. */
   map[f++] = SNAP_MKPC(J->pc);  /* The current PC is always the first entry. */
+  lua_assert(!J->pt ||
+	     (J->pc >= proto_bc(J->pt) &&
+	      J->pc < proto_bc(J->pt) + J->pt->sizebc));
   while (frame > lim) {  /* Backwards traversal of all frames above base. */
   while (frame > lim) {  /* Backwards traversal of all frames above base. */
     if (frame_islua(frame)) {
     if (frame_islua(frame)) {
       map[f++] = SNAP_MKPC(frame_pc(frame));
       map[f++] = SNAP_MKPC(frame_pc(frame));