summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp8
-rw-r--r--js/src/jit-test/tests/parser/bug-1357075.js10
-rw-r--r--js/src/jit/BaselineCompiler.cpp6
-rw-r--r--js/src/jit/BaselineCompiler.h7
-rw-r--r--js/src/jit/IonBuilder.cpp1
-rw-r--r--js/src/vm/Interpreter.cpp5
-rw-r--r--js/src/vm/Opcodes.h11
7 files changed, 43 insertions, 5 deletions
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp
index b2e48d7ea..4d3b60c2f 100644
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5318,6 +5318,14 @@ BytecodeEmitter::wrapWithDestructuringIteratorCloseTryNote(int32_t iterDepth, In
{
MOZ_ASSERT(this->stackDepth >= iterDepth);
+ // Pad a nop at the beginning of the bytecode covered by the trynote so
+ // that when unwinding environments, we may unwind to the scope
+ // corresponding to the pc *before* the start, in case the first bytecode
+ // emitted by |emitter| is the start of an inner scope. See comment above
+ // UnwindEnvironmentToTryPc.
+ if (!emit1(JSOP_TRY_DESTRUCTURING_ITERCLOSE))
+ return false;
+
ptrdiff_t start = offset();
if (!emitter(this))
return false;
diff --git a/js/src/jit-test/tests/parser/bug-1357075.js b/js/src/jit-test/tests/parser/bug-1357075.js
new file mode 100644
index 000000000..47482e372
--- /dev/null
+++ b/js/src/jit-test/tests/parser/bug-1357075.js
@@ -0,0 +1,10 @@
+// |jit-test| error: TypeError
+
+var iterable = {};
+var iterator = {
+ return: 1
+};
+iterable[Symbol.iterator] = function() {
+ return iterator;
+};
+for ([ class get {} ().iterator ] of [iterable]) {}
diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp
index 07d8e629d..3fa5a80ed 100644
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1063,6 +1063,12 @@ BaselineCompiler::emit_JSOP_NOP_DESTRUCTURING()
}
bool
+BaselineCompiler::emit_JSOP_TRY_DESTRUCTURING_ITERCLOSE()
+{
+ return true;
+}
+
+bool
BaselineCompiler::emit_JSOP_LABEL()
{
return true;
diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h
index 0bacf6f18..6b5bf009e 100644
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -226,7 +226,7 @@ namespace jit {
_(JSOP_SPREADSUPERCALL) \
_(JSOP_THROWSETCONST) \
_(JSOP_THROWSETALIASEDCONST) \
- _(JSOP_THROWSETCALLEE) \
+ _(JSOP_THROWSETCALLEE) \
_(JSOP_INITHIDDENPROP_GETTER) \
_(JSOP_INITHIDDENPROP_SETTER) \
_(JSOP_INITHIDDENELEM) \
@@ -234,8 +234,9 @@ namespace jit {
_(JSOP_INITHIDDENELEM_SETTER) \
_(JSOP_CHECKOBJCOERCIBLE) \
_(JSOP_DEBUGCHECKSELFHOSTED) \
- _(JSOP_JUMPTARGET) \
- _(JSOP_IS_CONSTRUCTING)
+ _(JSOP_JUMPTARGET) \
+ _(JSOP_IS_CONSTRUCTING) \
+ _(JSOP_TRY_DESTRUCTURING_ITERCLOSE)
class BaselineCompiler : public BaselineCompilerSpecific
{
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index ed09fb504..54d05cac4 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1678,6 +1678,7 @@ IonBuilder::inspectOpcode(JSOp op)
switch (op) {
case JSOP_NOP:
case JSOP_NOP_DESTRUCTURING:
+ case JSOP_TRY_DESTRUCTURING_ITERCLOSE:
case JSOP_LINENO:
case JSOP_LOOPENTRY:
case JSOP_JUMPTARGET:
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index d20e5284d..b747e4d7a 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1080,6 +1080,9 @@ js::UnwindEnvironmentToTryPc(JSScript* script, JSTryNote* tn)
if (tn->kind == JSTRY_CATCH || tn->kind == JSTRY_FINALLY) {
pc -= JSOP_TRY_LENGTH;
MOZ_ASSERT(*pc == JSOP_TRY);
+ } else if (tn->kind == JSTRY_DESTRUCTURING_ITERCLOSE) {
+ pc -= JSOP_TRY_DESTRUCTURING_ITERCLOSE_LENGTH;
+ MOZ_ASSERT(*pc == JSOP_TRY_DESTRUCTURING_ITERCLOSE);
}
return pc;
}
@@ -1917,7 +1920,7 @@ CASE(JSOP_UNUSED192)
CASE(JSOP_UNUSED209)
CASE(JSOP_UNUSED210)
CASE(JSOP_UNUSED211)
-CASE(JSOP_UNUSED220)
+CASE(JSOP_TRY_DESTRUCTURING_ITERCLOSE)
CASE(JSOP_UNUSED221)
CASE(JSOP_UNUSED222)
CASE(JSOP_UNUSED223)
diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h
index 3848445ff..4b044c8d8 100644
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -2211,7 +2211,16 @@
* Stack: result => result, callable
*/ \
macro(JSOP_CHECKISCALLABLE, 219, "checkiscallable", NULL, 2, 1, 1, JOF_UINT8) \
- macro(JSOP_UNUSED220, 220,"unused220", NULL, 1, 0, 0, JOF_BYTE) \
+ \
+ /*
+ * No-op used by the exception unwinder to determine the correct
+ * environment to unwind to when performing IteratorClose due to
+ * destructuring.
+ * Category: Other
+ * Operands:
+ * Stack: =>
+ */ \
+ macro(JSOP_TRY_DESTRUCTURING_ITERCLOSE, 220, "try-destructuring-iterclose", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED221, 221,"unused221", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED222, 222,"unused222", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED223, 223,"unused223", NULL, 1, 0, 0, JOF_BYTE) \