Title: [278888] trunk/Source/_javascript_Core
Revision
278888
Author
keith_mil...@apple.com
Date
2021-06-15 11:39:27 -0700 (Tue, 15 Jun 2021)

Log Message

Shouldn't drain the micro task queue when calling out to ObjC
https://bugs.webkit.org/show_bug.cgi?id=161942

Unreviewed, relanding r278734.


* API/tests/testapi.cpp:
(TestAPI::promiseDrainDoesNotEatExceptions):
(testCAPIViaCpp):
* API/tests/testapi.mm:
(testMicrotaskWithFunction):
(testObjectiveCAPI):
* runtime/JSLock.cpp:
(JSC::JSLock::willReleaseLock):
* runtime/ObjectPrototype.cpp:
(JSC::isPokerBros):
* runtime/VM.cpp:
(JSC::VM::didExhaustMicrotaskQueue):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/tests/testapi.cpp (278887 => 278888)


--- trunk/Source/_javascript_Core/API/tests/testapi.cpp	2021-06-15 18:25:07 UTC (rev 278887)
+++ trunk/Source/_javascript_Core/API/tests/testapi.cpp	2021-06-15 18:39:27 UTC (rev 278888)
@@ -38,6 +38,10 @@
 #include <wtf/Vector.h>
 #include <wtf/text/StringCommon.h>
 
+#if PLATFORM(COCOA)
+#include <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
+#endif
+
 extern "C" void configureJSCForTesting();
 extern "C" int testCAPIViaCpp(const char* filter);
 extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef);
@@ -147,6 +151,7 @@
     void promiseUnhandledRejection();
     void promiseUnhandledRejectionFromUnhandledRejectionCallback();
     void promiseEarlyHandledRejections();
+    void promiseDrainDoesNotEatExceptions();
     void topCallFrameAccess();
     void markedJSValueArrayAndGC();
     void classDefinitionWithJSSubclass();
@@ -609,6 +614,28 @@
     check(!callbackCalled, "unhandled rejection callback should not be called for asynchronous early-handled rejection");
 }
 
+void TestAPI::promiseDrainDoesNotEatExceptions()
+{
+#if PLATFORM(COCOA)
+    bool useLegacyDrain = false;
+#if PLATFORM(MAC)
+    useLegacyDrain = applicationSDKVersion() < DYLD_MACOSX_VERSION_12_00;
+#elif PLATFORM(WATCH)
+        // Don't check, JSC isn't API on watch anyway.
+#elif PLATFORM(IOS_FAMILY)
+    useLegacyDrain = applicationSDKVersion() < DYLD_IOS_VERSION_15_0;
+#else
+#error "Unsupported Cocoa Platform"
+#endif
+    if (useLegacyDrain)
+        return;
+#endif
+
+    ScriptResult result = callFunction("(function() { Promise.resolve().then(() => { throw 2; }); throw 1; })");
+    check(!result, "function should throw an error");
+    check(JSValueIsNumber(context, result.error()) && JSValueToNumber(context, result.error(), nullptr) == 1, "exception payload should have been 1");
+}
+
 void TestAPI::topCallFrameAccess()
 {
     {
@@ -760,6 +787,7 @@
     RUN(promiseRejectTrue());
     RUN(promiseUnhandledRejection());
     RUN(promiseUnhandledRejectionFromUnhandledRejectionCallback());
+    RUN(promiseDrainDoesNotEatExceptions());
     RUN(promiseEarlyHandledRejections());
     RUN(markedJSValueArrayAndGC());
     RUN(classDefinitionWithJSSubclass());
@@ -766,10 +794,8 @@
     RUN(proxyReturnedWithJSSubclassing());
     RUN(testJSObjectSetOnGlobalObjectSubclassDefinition());
 
-    if (tasks.isEmpty()) {
-        dataLogLn("Filtered all tests: ERROR");
-        return 1;
-    }
+    if (tasks.isEmpty())
+        return 0;
 
     Lock lock;
 

Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (278887 => 278888)


--- trunk/Source/_javascript_Core/API/tests/testapi.mm	2021-06-15 18:25:07 UTC (rev 278887)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm	2021-06-15 18:39:27 UTC (rev 278888)
@@ -41,6 +41,11 @@
 #import "Regress141809.h"
 #import <wtf/spi/darwin/DataVaultSPI.h>
 
+
+#if PLATFORM(COCOA)
+#import <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
+#endif
+
 #if __has_include(<libproc.h>)
 #define HAS_LIBPROC 1
 #import <libproc.h>
@@ -2730,6 +2735,40 @@
     }
 }
 
+static void testMicrotaskWithFunction()
+{
+    @autoreleasepool {
+#if PLATFORM(COCOA)
+        bool useLegacyDrain = false;
+#if PLATFORM(MAC)
+        useLegacyDrain = applicationSDKVersion() < DYLD_MACOSX_VERSION_12_00;
+#elif PLATFORM(WATCH)
+            // Don't check, JSC isn't API on watch anyway.
+#elif PLATFORM(IOS_FAMILY)
+        useLegacyDrain = applicationSDKVersion() < DYLD_IOS_VERSION_15_0;
+#else
+#error "Unsupported Cocoa Platform"
+#endif
+        if (useLegacyDrain)
+            return;
+#endif
+
+        JSContext *context = [[JSContext alloc] init];
+
+        JSValue *globalObject = context.globalObject;
+
+        auto block = ^() {
+            return 1+1;
+        };
+
+        [globalObject setValue:block forProperty:@"setTimeout"];
+        JSValue *arr = [context evaluateScript:@"var arr = []; (async () => { await 1; arr.push(3); })(); arr.push(1); setTimeout(); arr.push(2); arr;"];
+        checkResult(@"arr[0] should be 1", [arr[@0] toInt32] == 1);
+        checkResult(@"arr[1] should be 2", [arr[@1] toInt32] == 2);
+        checkResult(@"arr[2] should be 3", [arr[@2] toInt32] == 3);
+    }
+}
+
 @protocol ToString <JSExport>
 - (NSString *)toString;
 @end
@@ -2848,6 +2887,8 @@
     RUN(promiseCreateRejected());
     RUN(parallelPromiseResolveTest());
 
+    RUN(testMicrotaskWithFunction());
+
     if (!filter)
         testObjectiveCAPIMain();
 }

Modified: trunk/Source/_javascript_Core/ChangeLog (278887 => 278888)


--- trunk/Source/_javascript_Core/ChangeLog	2021-06-15 18:25:07 UTC (rev 278887)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-06-15 18:39:27 UTC (rev 278888)
@@ -1,3 +1,23 @@
+2021-06-15  Keith Miller  <keith_mil...@apple.com>
+
+        Shouldn't drain the micro task queue when calling out to ObjC
+        https://bugs.webkit.org/show_bug.cgi?id=161942
+
+        Unreviewed, relanding r278734.
+
+        * API/tests/testapi.cpp:
+        (TestAPI::promiseDrainDoesNotEatExceptions):
+        (testCAPIViaCpp):
+        * API/tests/testapi.mm:
+        (testMicrotaskWithFunction):
+        (testObjectiveCAPI):
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::willReleaseLock):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::isPokerBros):
+        * runtime/VM.cpp:
+        (JSC::VM::didExhaustMicrotaskQueue):
+
 2021-06-15  Michael Catanzaro  <mcatanz...@gnome.org>
 
         -Warray-bounds warning in Packed.h

Modified: trunk/Source/_javascript_Core/runtime/JSLock.cpp (278887 => 278888)


--- trunk/Source/_javascript_Core/runtime/JSLock.cpp	2021-06-15 18:25:07 UTC (rev 278887)
+++ trunk/Source/_javascript_Core/runtime/JSLock.cpp	2021-06-15 18:39:27 UTC (rev 278888)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2005-2021 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -33,6 +33,10 @@
 #include <wtf/ios/WebCoreThread.h>
 #endif
 
+#if PLATFORM(COCOA)
+#include <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
+#endif
+
 namespace JSC {
 
 Lock GlobalJSLock::s_sharedInstanceMutex;
@@ -197,8 +201,25 @@
 {   
     RefPtr<VM> vm = m_vm;
     if (vm) {
-        vm->drainMicrotasks();
+        static bool useLegacyDrain = false;
+#if PLATFORM(COCOA)
+        static std::once_flag once;
+        std::call_once(once, [] {
+#if PLATFORM(MAC)
+            useLegacyDrain = applicationSDKVersion() < DYLD_MACOSX_VERSION_12_00;
+#elif PLATFORM(WATCH)
+            // Don't check, JSC isn't API on watch anyway.
+#elif PLATFORM(IOS_FAMILY)
+            useLegacyDrain = applicationSDKVersion() < DYLD_IOS_VERSION_15_0;
+#else
+#error "Unsupported Cocoa Platform"
+#endif
+        });
+#endif
 
+        if (!m_lockDropDepth || useLegacyDrain)
+            vm->drainMicrotasks();
+
         if (!vm->topCallFrame)
             vm->clearLastException();
 

Modified: trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp (278887 => 278888)


--- trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp	2021-06-15 18:25:07 UTC (rev 278887)
+++ trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp	2021-06-15 18:39:27 UTC (rev 278888)
@@ -29,7 +29,7 @@
 #include "PropertySlot.h"
 
 #if PLATFORM(IOS)
-#include <wtf/spi/darwin/dyldSPI.h>
+#include <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
 #endif
 
 namespace JSC {
@@ -322,7 +322,7 @@
     auto bundleID = CFBundleGetIdentifier(CFBundleGetMainBundle());
     return bundleID
         && CFEqual(bundleID, CFSTR("com.kpgame.PokerBros"))
-        && dyld_get_program_sdk_version() < DYLD_IOS_VERSION_14_0;
+        && applicationSDKVersion() < DYLD_IOS_VERSION_14_0;
 }
 #endif
 

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (278887 => 278888)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2021-06-15 18:25:07 UTC (rev 278887)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2021-06-15 18:39:27 UTC (rev 278888)
@@ -1368,13 +1368,15 @@
 
 void VM::didExhaustMicrotaskQueue()
 {
-    auto unhandledRejections = WTFMove(m_aboutToBeNotifiedRejectedPromises);
-    for (auto& promise : unhandledRejections) {
-        if (promise->isHandled(*this))
-            continue;
+    do {
+        auto unhandledRejections = WTFMove(m_aboutToBeNotifiedRejectedPromises);
+        for (auto& promise : unhandledRejections) {
+            if (promise->isHandled(*this))
+                continue;
 
-        callPromiseRejectionCallback(promise);
-    }
+            callPromiseRejectionCallback(promise);
+        }
+    } while (!m_aboutToBeNotifiedRejectedPromises.isEmpty());
 }
 
 void VM::promiseRejected(JSPromise* promise)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to