Checkpoint inlined call return handler needs an exception check when dispatching
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 May 2020 18:01:21 +0000 (18:01 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 May 2020 18:01:21 +0000 (18:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=212104

Reviewed by Yusuke Suzuki.

JSTests:

* stress/for-of-done-getter-osr-exits-inlined-to-value-getter-with-exception.js: Added.
(let.d.get done):
(let.d.get value):
(foo):
(catch):

Source/JavaScriptCore:

* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::dispatchToNextInstruction):
(JSC::LLInt::slow_path_checkpoint_osr_exit_from_inlined_call):
(JSC::LLInt::slow_path_checkpoint_osr_exit):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262064 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/for-of-done-getter-osr-exits-inlined-to-value-getter-with-exception.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

index 0fce85d..62919d4 100644 (file)
@@ -1,3 +1,16 @@
+2020-05-22  Keith Miller  <keith_miller@apple.com>
+
+        Checkpoint inlined call return handler needs an exception check when dispatching
+        https://bugs.webkit.org/show_bug.cgi?id=212104
+
+        Reviewed by Yusuke Suzuki.
+
+        * stress/for-of-done-getter-osr-exits-inlined-to-value-getter-with-exception.js: Added.
+        (let.d.get done):
+        (let.d.get value):
+        (foo):
+        (catch):
+
 2020-05-21  Alexey Shvayka  <shvaikalesh@gmail.com>
 
         Use @isUndefinedOrNull instead of abstract equality with null
diff --git a/JSTests/stress/for-of-done-getter-osr-exits-inlined-to-value-getter-with-exception.js b/JSTests/stress/for-of-done-getter-osr-exits-inlined-to-value-getter-with-exception.js
new file mode 100644 (file)
index 0000000..266bbb1
--- /dev/null
@@ -0,0 +1,41 @@
+let i = 10000;
+let e;
+let d = {
+    get done() {
+        let result = !(--i);
+        if (i % 5000 == 0)
+            OSRExit();
+        return result;
+    },
+
+    get value() {
+        if (i % 5000 == 0)
+            throw e = new Error();
+        return i;
+    }
+};
+
+let x = {
+    next: ()=>d
+}
+
+let iter = {};
+iter[Symbol.iterator] = ()=>x;
+
+function foo() {
+    for (let x of iter) {
+        if (x !== --oldI)
+            throw new Error();
+    }
+}
+
+let oldI = i;
+try {
+    foo();
+} catch (error) {
+    if (e !== error)
+        throw error
+}
+
+if (!e)
+    throw new Error();
index 9c08070..300fa66 100644 (file)
@@ -1,3 +1,15 @@
+2020-05-22  Keith Miller  <keith_miller@apple.com>
+
+        Checkpoint inlined call return handler needs an exception check when dispatching
+        https://bugs.webkit.org/show_bug.cgi?id=212104
+
+        Reviewed by Yusuke Suzuki.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::dispatchToNextInstruction):
+        (JSC::LLInt::slow_path_checkpoint_osr_exit_from_inlined_call):
+        (JSC::LLInt::slow_path_checkpoint_osr_exit):
+
 2020-05-22  Paulo Matos  <pmatos@igalia.com>
 
         Fix non-unified builds for i386 build
index 7402c0d..1d0615c 100644 (file)
@@ -2086,9 +2086,11 @@ static void handleIteratorNextCheckpoint(VM& vm, CallFrame* callFrame, JSGlobalO
         valueRegister = iteratorResultObject.get(globalObject, vm.propertyNames->value);
 }
 
-inline SlowPathReturnType dispatchToNextInstruction(CodeBlock* codeBlock, InstructionStream::Ref pc)
+inline SlowPathReturnType dispatchToNextInstruction(ThrowScope& scope, CodeBlock* codeBlock, InstructionStream::Ref pc)
 {
-    RELEASE_ASSERT(!codeBlock->vm().exceptionForInspection());
+    if (scope.exception())
+        return encodeResult(returnToThrow(scope.vm()), nullptr);
+
     if (Options::forceOSRExitToLLInt() || codeBlock->jitType() == JITType::InterpreterThunk) {
         const Instruction* nextPC = pc.next().ptr();
         auto nextBytecode = LLInt::getCodePtr<JSEntryPtrTag>(*pc.next().ptr());
@@ -2110,6 +2112,7 @@ extern "C" SlowPathReturnType slow_path_checkpoint_osr_exit_from_inlined_call(Ca
     CodeBlock* codeBlock = callFrame->codeBlock();
     VM& vm = codeBlock->vm();
     SlowPathFrameTracer tracer(vm, callFrame);
+    auto scope = DECLARE_THROW_SCOPE(vm);
 
     std::unique_ptr<CheckpointOSRExitSideState> sideState = vm.findCheckpointOSRSideState(callFrame);
     BytecodeIndex bytecodeIndex = sideState->bytecodeIndex;
@@ -2150,7 +2153,7 @@ extern "C" SlowPathReturnType slow_path_checkpoint_osr_exit_from_inlined_call(Ca
         break;
     }
 
-    return dispatchToNextInstruction(codeBlock, pc);
+    return dispatchToNextInstruction(scope, codeBlock, pc);
 }
 
 extern "C" SlowPathReturnType slow_path_checkpoint_osr_exit(CallFrame* callFrame, EncodedJSValue /* needed for cCall2 in CLoop */)
@@ -2194,10 +2197,8 @@ extern "C" SlowPathReturnType slow_path_checkpoint_osr_exit(CallFrame* callFrame
         RELEASE_ASSERT_NOT_REACHED();
         break;
     }
-    if (UNLIKELY(scope.exception()))
-        return encodeResult(returnToThrow(vm), nullptr);
 
-    return dispatchToNextInstruction(codeBlock, pc);
+    return dispatchToNextInstruction(scope, codeBlock, pc);
 }
 
 extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)