summaryrefslogtreecommitdiff
path: root/js/src/jit/JitFrames.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/JitFrames.cpp')
-rw-r--r--js/src/jit/JitFrames.cpp82
1 files changed, 60 insertions, 22 deletions
diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp
index d6c6fc4c93..30bbd0b9bc 100644
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -330,28 +330,44 @@ NumArgAndLocalSlots(const InlineFrameIterator& frame)
static void
CloseLiveIteratorIon(JSContext* cx, const InlineFrameIterator& frame, JSTryNote* tn)
{
- MOZ_ASSERT(tn->kind == JSTRY_FOR_IN || tn->kind == JSTRY_ITERCLOSE);
- MOZ_ASSERT(tn->stackDepth > 0);
+ MOZ_ASSERT(tn->kind == JSTRY_FOR_IN ||
+ tn->kind == JSTRY_ITERCLOSE ||
+ tn->kind == JSTRY_DESTRUCTURING_ITERCLOSE);
+
+ bool isDestructuring = tn->kind == JSTRY_DESTRUCTURING_ITERCLOSE;
+ MOZ_ASSERT_IF(!isDestructuring, tn->stackDepth > 0);
+ MOZ_ASSERT_IF(isDestructuring, tn->stackDepth > 1);
SnapshotIterator si = frame.snapshotIterator();
- // Skip stack slots until we reach the iterator object.
+ // Skip stack slots until we reach the iterator object on the stack. For
+ // the destructuring case, we also need to get the "done" value.
uint32_t stackSlot = tn->stackDepth;
- uint32_t skipSlots = NumArgAndLocalSlots(frame) + stackSlot - 1;
+ uint32_t adjust = isDestructuring ? 2 : 1;
+ uint32_t skipSlots = NumArgAndLocalSlots(frame) + stackSlot - adjust;
for (unsigned i = 0; i < skipSlots; i++)
si.skip();
Value v = si.read();
- RootedObject obj(cx, &v.toObject());
+ RootedObject iterObject(cx, &v.toObject());
+
+ if (isDestructuring) {
+ Value v = si.read();
+ MOZ_ASSERT(v.isBoolean());
+ // Do not call IteratorClose if the destructuring iterator is already
+ // done.
+ if (v.isTrue())
+ return;
+ }
if (cx->isExceptionPending()) {
if (tn->kind == JSTRY_FOR_IN)
- UnwindIteratorForException(cx, obj);
+ UnwindIteratorForException(cx, iterObject);
else
- IteratorCloseForException(cx, obj);
+ IteratorCloseForException(cx, iterObject);
} else {
- UnwindIteratorForUncatchableException(cx, obj);
+ UnwindIteratorForUncatchableException(cx, iterObject);
}
}
@@ -426,14 +442,12 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx
switch (tn->kind) {
case JSTRY_FOR_IN:
- case JSTRY_ITERCLOSE: {
+ case JSTRY_ITERCLOSE:
+ case JSTRY_DESTRUCTURING_ITERCLOSE:
MOZ_ASSERT_IF(tn->kind == JSTRY_FOR_IN,
JSOp(*(script->main() + tn->start + tn->length)) == JSOP_ENDITER);
- MOZ_ASSERT(tn->stackDepth > 0);
-
CloseLiveIteratorIon(cx, frame, tn);
break;
- }
case JSTRY_FOR_OF:
case JSTRY_LOOP:
@@ -607,28 +621,52 @@ ProcessTryNotesBaseline(JSContext* cx, const JitFrameIterator& frame, Environmen
return true;
}
- case JSTRY_FOR_IN:
- case JSTRY_ITERCLOSE: {
+ case JSTRY_FOR_IN: {
uint8_t* framePointer;
uint8_t* stackPointer;
BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer);
- Value iterValue(*(reinterpret_cast<Value*>(stackPointer)));
+ Value iterValue(*reinterpret_cast<Value*>(stackPointer));
RootedObject iterObject(cx, &iterValue.toObject());
- bool ok;
- if (tn->kind == JSTRY_FOR_IN)
- ok = UnwindIteratorForException(cx, iterObject);
- else
- ok = IteratorCloseForException(cx, iterObject);
- if (!ok) {
+ if (!UnwindIteratorForException(cx, iterObject)) {
// See comment in the JSTRY_FOR_IN case in Interpreter.cpp's
// ProcessTryNotes.
SettleOnTryNote(cx, tn, frame, ei, rfe, pc);
- MOZ_ASSERT_IF(tn->kind == JSTRY_FOR_IN, **pc == JSOP_ENDITER);
+ MOZ_ASSERT(**pc == JSOP_ENDITER);
+ return false;
+ }
+ break;
+ }
+
+ case JSTRY_ITERCLOSE: {
+ uint8_t* framePointer;
+ uint8_t* stackPointer;
+ BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer);
+ Value iterValue(*reinterpret_cast<Value*>(stackPointer));
+ RootedObject iterObject(cx, &iterValue.toObject());
+ if (!IteratorCloseForException(cx, iterObject)) {
+ SettleOnTryNote(cx, tn, frame, ei, rfe, pc);
return false;
}
break;
}
+ case JSTRY_DESTRUCTURING_ITERCLOSE: {
+ uint8_t* framePointer;
+ uint8_t* stackPointer;
+ BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer);
+ Value doneValue(*(reinterpret_cast<Value*>(stackPointer)));
+ MOZ_ASSERT(doneValue.isBoolean());
+ if (doneValue.isFalse()) {
+ Value iterValue(*(reinterpret_cast<Value*>(stackPointer) + 1));
+ RootedObject iterObject(cx, &iterValue.toObject());
+ if (!IteratorCloseForException(cx, iterObject)) {
+ SettleOnTryNote(cx, tn, frame, ei, rfe, pc);
+ return false;
+ }
+ }
+ break;
+ }
+
case JSTRY_FOR_OF:
case JSTRY_LOOP:
break;