summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/src/jit-test/tests/ion/bug1334314.js16
-rw-r--r--js/src/jit/BaselineBailouts.cpp41
2 files changed, 48 insertions, 9 deletions
diff --git a/js/src/jit-test/tests/ion/bug1334314.js b/js/src/jit-test/tests/ion/bug1334314.js
new file mode 100644
index 000000000..488fc9027
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1334314.js
@@ -0,0 +1,16 @@
+// |jit-test| error: TypeError
+
+var g = newGlobal();
+g.parent = this;
+g.eval("new Debugger(parent).onExceptionUnwind = function () { };");
+
+function f() {
+ [[]] = [];
+}
+try {
+ f();
+} catch (e) {};
+try {
+ f();
+} catch (e) {};
+f();
diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp
index 8fc8a522d..161e1aa4c 100644
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -487,7 +487,7 @@ GetNextNonLoopEntryPc(jsbytecode* pc)
}
static bool
-HasLiveIteratorAtStackDepth(JSScript* script, jsbytecode* pc, uint32_t stackDepth)
+HasLiveStackValueAtDepth(JSScript* script, jsbytecode* pc, uint32_t stackDepth)
{
if (!script->hasTrynotes())
return false;
@@ -501,14 +501,37 @@ HasLiveIteratorAtStackDepth(JSScript* script, jsbytecode* pc, uint32_t stackDept
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;
+ switch (tn->kind) {
+ case JSTRY_FOR_IN:
+ // For-in loops have only the iterator on stack.
+ if (stackDepth == tn->stackDepth)
+ return true;
+ break;
+
+ case JSTRY_FOR_OF:
+ // For-of loops have both the iterator and the result object on
+ // stack. The iterator is below the result object.
+ if (stackDepth == tn->stackDepth - 1)
+ return true;
+ break;
+
+ case JSTRY_ITERCLOSE:
+ // Code that need to call IteratorClose have the iterator on the
+ // stack.
+ if (stackDepth == tn->stackDepth)
+ return true;
+ break;
- // 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;
+ case JSTRY_DESTRUCTURING_ITERCLOSE:
+ // Destructuring code that need to call IteratorClose have both
+ // the iterator and the "done" value on the stack.
+ if (stackDepth == tn->stackDepth || stackDepth == tn->stackDepth - 1)
+ return true;
+ break;
+
+ default:
+ break;
+ }
}
return false;
@@ -945,7 +968,7 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC,
// iterators, however, so read them out. They will be closed by
// HandleExceptionBaseline.
MOZ_ASSERT(cx->compartment()->isDebuggee());
- if (iter.moreFrames() || HasLiveIteratorAtStackDepth(script, pc, i + 1)) {
+ if (iter.moreFrames() || HasLiveStackValueAtDepth(script, pc, i + 1)) {
v = iter.read();
} else {
iter.skip();