[INFER] Trap fixes when rejoining to interpreter, bug 659337.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 25 May 2011 08:26:29 -0700
changeset 75106 0d3bcf8e0bb864b3799ec04276e971ef6b1ab221
parent 75105 79746474b25ad9a076ef3e3892b1cdca1d53311c
child 75107 7ae647fe972fe7381939816de9c4305c1171c590
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs659337
milestone6.0a1
[INFER] Trap fixes when rejoining to interpreter, bug 659337.
js/src/jit-test/tests/basic/bug657975.js
js/src/methodjit/InvokeHelpers.cpp
--- a/js/src/jit-test/tests/basic/bug657975.js
+++ b/js/src/jit-test/tests/basic/bug657975.js
@@ -39,8 +39,41 @@ trap(f6, 10, '')
 f6()
 
 // bug 658491
 function f7() {
   try { y = w; } catch(y) {}
 }
 trap(f7, 16, '')
 f7()
+
+// bug 658950
+f8 = (function() {
+  let x;
+  yield
+})
+trap(f8, 6, undefined);
+for (a in f8())
+  (function() {})()
+
+// bug 659043
+f9 = (function() {
+  for (let a = 0; a < 0; ++a) {
+    for each(let w in []) {}
+  }
+})
+trap(f9, 27, undefined);
+for (b in f9())
+  (function() {})()
+
+// bug 659233
+f10 = (function() {
+    while (h) {
+        continue
+    }
+})
+trap(f10, 0, '');
+try { f10() } catch (e) {}
+
+// bug 659337
+f11 = Function("for (x = 0; x < 6; x++) { gc() }");
+trap(f11, 23, '');
+f11()
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -1186,17 +1186,17 @@ static const char *OpcodeNames[] = {
 static void
 FinishVarIncOp(VMFrame &f, RejoinState rejoin, Value ov, Value nv, Value *vp)
 {
     /* Finish an increment operation on a LOCAL or ARG. These do not involve property accesses. */
     JS_ASSERT(rejoin == REJOIN_POS || rejoin == REJOIN_BINARY);
 
     JSContext *cx = f.cx;
 
-    JSOp op = JSOp(*f.pc());
+    JSOp op = js_GetOpcode(cx, f.script(), f.pc());
     const JSCodeSpec *cs = &js_CodeSpec[op];
 
     unsigned i = GET_SLOTNO(f.pc());
     Value *var = (JOF_TYPE(cs->format) == JOF_LOCAL) ? f.fp()->slots() + i : &f.fp()->formalArg(i);
 
     if (rejoin == REJOIN_POS) {
         double d = ov.toNumber();
         double N = (cs->format & JOF_INC) ? 1 : -1;
@@ -1219,17 +1219,17 @@ FinishObjIncOp(VMFrame &f, RejoinState r
               rejoin == REJOIN_POS || rejoin == REJOIN_BINARY);
 
     JSContext *cx = f.cx;
 
     JSObject *obj = ValueToObject(cx, &objv);
     if (!obj)
         return false;
 
-    JSOp op = JSOp(*f.pc());
+    JSOp op = js_GetOpcode(cx, f.script(), f.pc());
     const JSCodeSpec *cs = &js_CodeSpec[op];
     JS_ASSERT(JOF_TYPE(cs->format) == JOF_ATOM);
 
     jsid id = ATOM_TO_JSID(f.script()->getAtom(GET_SLOTNO(f.pc())));
 
     if (rejoin == REJOIN_BINDNAME && !obj->getProperty(cx, id, &ov))
         return false;
 
@@ -1601,16 +1601,17 @@ js_InternalInterpret(void *returnData, v
 
       case REJOIN_BRANCH: {
         /*
          * This must be an opcode fused with IFNE/IFEQ. Unfused IFNE/IFEQ are
          * implemented in terms of ValueToBoolean, which is infallible and
          * cannot trigger recompilation.
          */
         bool takeBranch = false;
+        analyze::UntrapOpcode untrap(cx, script, nextpc);
         switch (JSOp(*nextpc)) {
           case JSOP_IFNE:
           case JSOP_IFNEX:
             takeBranch = returnReg != NULL;
             break;
           case JSOP_IFEQ:
           case JSOP_IFEQX:
             takeBranch = returnReg == NULL;