Bug 1149510 - Don't try to read the result object when doing in-place debug mode bailout in a for-of loop. r=jandem, a=lizzard
authorShu-yu Guo <shu@rfrn.org>
Fri, 03 Apr 2015 14:18:05 -0700
changeset 267057 692922cc239c15a6cb944f03892efb8fe0242ba8
parent 267056 a5578b2096e47710def4c46fdab638c1603ffb48
child 267058 a7ba1ecfd134e8bd084c56114b2a29ba22165a87
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, lizzard
bugs1149510
milestone39.0a2
Bug 1149510 - Don't try to read the result object when doing in-place debug mode bailout in a for-of loop. r=jandem, a=lizzard
js/src/jit-test/tests/debug/onExceptionUnwind-15.js
js/src/jit/BaselineBailouts.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/onExceptionUnwind-15.js
@@ -0,0 +1,25 @@
+// Test that Ion->Baseline in-place debug mode bailout can recover the iterator
+// from the snapshot in a for-of loop.
+
+g = newGlobal();
+g.parent = this;
+g.eval("Debugger(parent).onExceptionUnwind=(function() {})");
+function throwInNext() {
+  yield 1;
+  yield 2;
+  yield 3;
+  throw 42;
+}
+
+function f() {
+  for (var o of new throwInNext);
+}
+
+var log = "";
+try {
+  f();
+} catch (e) {
+  log += e;
+}
+
+assertEq(log, "42");
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -482,22 +482,20 @@ HasLiveIteratorAtStackDepth(JSScript* sc
             continue;
         if (pcOffset >= tn->start + tn->length)
             continue;
 
         // For-in loops have only the iterator on stack.
         if (tn->kind == JSTRY_FOR_IN && stackDepth == tn->stackDepth)
             return true;
 
-        // For-of loops have both the iterator and the result on stack.
-        if (tn->kind == JSTRY_FOR_OF &&
-            (stackDepth == tn->stackDepth || stackDepth == tn->stackDepth - 1))
-        {
+        // For-of loops have both the iterator and the result object on
+        // stack. The iterator is below the result object.
+        if (tn->kind == JSTRY_FOR_OF && stackDepth == tn->stackDepth - 1)
             return true;
-        }
     }
 
     return false;
 }
 
 // For every inline frame, we write out the following data:
 //
 //                      |      ...      |