Browse Source

LuaJIT-2.0.0-beta2 hotfix #2

Fix lua_tocfunction().
Fix cutoff register in JMP bytecode for some conditional expressions.
Fix PHI marking algorithm for references from variant slots.
Mike Pall 15 years ago
parent
commit
7b4f55ad89
3 changed files with 20 additions and 11 deletions
  1. 6 2
      src/lj_api.c
  2. 10 7
      src/lj_opt_loop.c
  3. 4 2
      src/lj_parse.c

+ 6 - 2
src/lj_api.c

@@ -486,8 +486,12 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
 LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
 {
   cTValue *o = index2adr(L, idx);
-  ASMFunction gate = funcV(o)->c.gate;
-  return (gate == lj_gate_c || gate == lj_gate_cwrap) ? funcV(o)->c.f : NULL;
+  if (tvisfunc(o)) {
+    ASMFunction gate = funcV(o)->c.gate;
+    if (gate == lj_gate_c || gate == lj_gate_cwrap)
+      return funcV(o)->c.f;
+  }
+  return NULL;
 }
 
 LUA_API void *lua_touserdata(lua_State *L, int idx)

+ 10 - 7
src/lj_opt_loop.c

@@ -131,15 +131,18 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi)
   nslots = J->baseslot+J->maxslot;
   for (i = 1; i < nslots; i++) {
     IRRef ref = tref_ref(J->slot[i]);
-    if (!irref_isk(ref) && ref != subst[ref]) {
+    while (!irref_isk(ref) && ref != subst[ref]) {
       IRIns *ir = IR(ref);
       irt_clearmark(ir->t);  /* Unmark potential uses, too. */
-      if (!irt_isphi(ir->t) && !irt_ispri(ir->t)) {
-	irt_setphi(ir->t);
-	if (nphi >= LJ_MAX_PHI)
-	  lj_trace_err(J, LJ_TRERR_PHIOV);
-	phi[nphi++] = (IRRef1)ref;
-      }
+      if (irt_isphi(ir->t) || irt_ispri(ir->t))
+	break;
+      irt_setphi(ir->t);
+      if (nphi >= LJ_MAX_PHI)
+	lj_trace_err(J, LJ_TRERR_PHIOV);
+      phi[nphi++] = (IRRef1)ref;
+      ref = subst[ref];
+      if (ref > invar)
+	break;
     }
   }
   /* Pass #4: emit PHI instructions or eliminate PHIs. */

+ 4 - 2
src/lj_parse.c

@@ -636,6 +636,7 @@ static void invertjump(FuncState *fs, ExpDesc *e)
 
 static BCPos jumponcond(FuncState *fs, ExpDesc *e, int cond)
 {
+  BCPos pc;
   if (e->k == VRELOCABLE) {
     BCIns *i = bcptr(fs, e);
     if (bc_op(*i) == BC_NOT) {
@@ -648,9 +649,10 @@ static BCPos jumponcond(FuncState *fs, ExpDesc *e, int cond)
     reserveregs(fs, 1);
     discharge2reg(fs, e, fs->freereg-1);
   }
-  freeexp(fs, e);
   emitAD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info);
-  return emit_jump(fs);
+  pc = emit_jump(fs);
+  freeexp(fs, e);
+  return pc;
 }
 
 static void goiftrue(FuncState *fs, ExpDesc *e)