Bug 911065 - Fix source notes for for/of loops. r=jorendorff
authorNick Fitzgerald <fitzgen@gmail.com>
Thu, 13 Nov 2014 13:58:00 -0500
changeset 240185 261e7681ed027a3b5da5e10b6b110e027c343ce2
parent 240184 8890eab664bf0660d4295162457397a42e9fcbb2
child 240186 b5fdc0c44b6c653babecfb14f2467de66eaee08a
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs911065
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 911065 - Fix source notes for for/of loops. r=jorendorff
js/src/frontend/BytecodeEmitter.cpp
js/src/jit-test/tests/debug/bug911065.js
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -4823,29 +4823,30 @@ EmitForInOrOfVariables(ExclusiveContext 
 static bool
 EmitForOf(ExclusiveContext *cx, BytecodeEmitter *bce, StmtType type, ParseNode *pn, ptrdiff_t top)
 {
     MOZ_ASSERT(type == STMT_FOR_OF_LOOP || type == STMT_SPREAD);
     MOZ_ASSERT_IF(type == STMT_FOR_OF_LOOP, pn && pn->pn_left->isKind(PNK_FOROF));
     MOZ_ASSERT_IF(type == STMT_SPREAD, !pn);
 
     ParseNode *forHead = pn ? pn->pn_left : nullptr;
+    ParseNode *forHeadExpr = forHead ? forHead->pn_kid3 : nullptr;
     ParseNode *forBody = pn ? pn->pn_right : nullptr;
 
     ParseNode *pn1 = forHead ? forHead->pn_kid1 : nullptr;
     bool letDecl = false;
     if (pn1 && !EmitForInOrOfVariables(cx, bce, pn1, &letDecl))
         return false;
 
     if (type == STMT_FOR_OF_LOOP) {
         // For-of loops run with two values on the stack: the iterator and the
         // current result object.
 
         // Compile the object expression to the right of 'of'.
-        if (!EmitTree(cx, bce, forHead->pn_kid3))
+        if (!EmitTree(cx, bce, forHeadExpr))
             return false;
         if (!EmitIterator(cx, bce))
             return false;
 
         // Push a dummy result so that we properly enter iteration midstream.
         if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)                // ITER RESULT
             return false;
     }
@@ -4915,17 +4916,17 @@ EmitForOf(ExclusiveContext *cx, Bytecode
 
         MOZ_ASSERT(bce->stackDepth == loopDepth - 1);
 
         // STMT_SPREAD never contain continue, so do not set "update" offset.
     }
 
     // COME FROM the beginning of the loop to here.
     SetJumpOffsetAt(bce, jmp);
-    if (!EmitLoopEntry(cx, bce, nullptr))
+    if (!EmitLoopEntry(cx, bce, forHeadExpr))
         return false;
 
     if (type == STMT_FOR_OF_LOOP) {
         if (Emit1(cx, bce, JSOP_POP) < 0)                      // ITER
             return false;
         if (Emit1(cx, bce, JSOP_DUP) < 0)                      // ITER ITER
             return false;
     } else {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug911065.js
@@ -0,0 +1,34 @@
+var g = newGlobal();
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+
+g.eval(`                        //  1
+var line0 = Error().lineNumber; //  2
+function f() {                  //  3
+    for (var x of [0]) {        //  4
+        if (true == false)      //  5
+            return false;       //  6, aka line0 + 4
+    }                           //  7
+    return true;                //  8
+}                               //  9
+`);                             // 10
+
+if (g.dis)
+  g.dis(g.f);
+
+var script = gw.getOwnPropertyDescriptor("f").value.script;
+
+print("Debugger's view:");
+print("----------------");
+for (var i = script.startLine; i <= script.startLine + script.lineCount; i++) {
+  print("Line " + i + ": " + JSON.stringify(script.getLineOffsets(i)));
+}
+
+var hits = 0;
+var handler = {hit: function () { hits++; }};
+var offs = script.getLineOffsets(g.line0 + 4);
+for (var i = 0; i < offs.length; i++)
+    script.setBreakpoint(offs[i], handler);
+
+assertEq(g.f(), true);
+assertEq(hits, 0);