From 2bb0252ab48a97a72c33cef9cbe54e86563f15c9 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sat, 24 Mar 2018 12:23:14 +0100 Subject: Bug 1147371: Implement IteratorClose for array destructuring Issue #74 --- js/src/jit/JitFrames.cpp | 82 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 22 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index d6c6fc4c9..30bbd0b9b 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(stackPointer))); + Value iterValue(*reinterpret_cast(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(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(stackPointer))); + MOZ_ASSERT(doneValue.isBoolean()); + if (doneValue.isFalse()) { + Value iterValue(*(reinterpret_cast(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; -- cgit v1.2.3