Title: [274764] trunk
Revision
274764
Author
da...@apple.com
Date
2021-03-22 11:45:13 -0700 (Mon, 22 Mar 2021)

Log Message

[Cocoa] Make it possible to release a WKWebView on a non-main thread without a crash due to WKScriptMessage race
https://bugs.webkit.org/show_bug.cgi?id=222336

Reviewed by Chris Dumez.

Source/_javascript_Core:

* API/ObjcRuntimeExtras.h: Removed declarations of objc_initWeak and objc_destroyWeak, since
these are already in <wtf/spi/cocoa/objcSPI.h>.

Source/WebKit:

* Platform/spi/Cocoa/objcSPI.h: Removed this unused file.

* UIProcess/API/C/mac/WKPagePrivateMac.mm:
(WKPageGetWebView): Use WKPageProxy::cocoaView instead of fromWebPageProxy.
* UIProcess/API/Cocoa/WKDownload.mm:
(-[WKDownload webView]): Ditto.
* UIProcess/API/Cocoa/WKFrameInfo.mm:
(-[WKFrameInfo webView]): Ditto.

* UIProcess/API/Cocoa/WKUserContentController.mm:
(ScriptMessageHandlerDelegate::didPostMessage): Use WKPageProxy::cocoaView
instead of fromWebPageProxy and add null checks.
(ScriptMessageHandlerDelegate::didPostMessageWithAsyncReply): Ditto.

* UIProcess/API/Cocoa/WKWebView.mm:
(pageToViewMap): Deleted.
(fromWebPageProxy): Deleted.
(-[WKWebView _initializeWithConfiguration:]): Use WKPageProxy::setCocoaView
instead of adding the page/view pair to a map.
(-[WKWebView dealloc]): Removed code that removed the page/view pair from the map.

* UIProcess/API/Cocoa/WKWebViewInternal.h: Removed fromWebPageProxy.

* UIProcess/API/Cocoa/_WKDownload.mm:
(-[_WKDownload originatingWebView]): Use WKPageProxy::cocoaView instead of fromWebPageProxy.
* UIProcess/API/Cocoa/_WKFrameTreeNode.mm:
(-[_WKFrameTreeNode webView]): Ditto.
* UIProcess/API/Cocoa/_WKInspector.mm:
(-[_WKInspector webView]): Ditto.
* UIProcess/API/Cocoa/_WKInspectorTesting.mm:
(-[_WKInspector inspectorWebView]): Ditto.

* UIProcess/Cocoa/AutomationSessionClient.mm:
(WebKit::AutomationSessionClient::requestSwitchToPage): Use WKPageProxy::cocoaView
instead of fromWebPageProxy and add a null check.
(WebKit::AutomationSessionClient::requestHideWindowOfPage): Ditto.
(WebKit::AutomationSessionClient::requestRestoreWindowOfPage): Ditto.
(WebKit::AutomationSessionClient::requestMaximizeWindowOfPage): Ditto.
(WebKit::AutomationSessionClient::isShowingJavaScriptDialogOnPage): Ditto.
(WebKit::AutomationSessionClient::dismissCurrentJavaScriptDialogOnPage): Ditto.
(WebKit::AutomationSessionClient::acceptCurrentJavaScriptDialogOnPage): Ditto.
(WebKit::AutomationSessionClient::messageOfCurrentJavaScriptDialogOnPage): Ditto.
(WebKit::AutomationSessionClient::setUserInputForCurrentJavaScriptPromptOnPage): Ditto.
(WebKit::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage): Ditto.
(WebKit::AutomationSessionClient::currentPresentationOfPage): Ditto.

* UIProcess/Cocoa/MediaPermissionUtilities.mm:
(WebKit::alertForPermission): Use WKPageProxy::cocoaView instead of fromWebPageProxy.

* UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm:
(WebKit::PopUpSOAuthorizationSession::abortInternal): Added a null check since
initSecretWebView is no longer guaranteed to allocate m_secretWebView in the case
where the WKWebView is nil.
(WebKit::PopUpSOAuthorizationSession::completeInternal): Ditto.
(WebKit::PopUpSOAuthorizationSession::initSecretWebView): Use WKPageProxy::cocoaView
instead of fromWebPageProxy and added a null check.

* UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm:
(WebKit::SOAuthorizationSession::continueStartAfterDecidePolicy): Use WKPageProxy::cocoaView
instead of fromWebPageProxy.

* UIProcess/Cocoa/WebURLSchemeHandlerCocoa.mm:
(WebKit::WebURLSchemeHandlerCocoa::platformStartTask): Use WKPageProxy::cocoaView
instead of fromWebPageProxy and added a null check.
(WebKit::WebURLSchemeHandlerCocoa::platformStopTask): Ditto. Also call the
new suppressTaskStoppedExceptions if we are unable to call the delegate method due to
the WKWebView already being nil.

* UIProcess/PDF/WKPDFHUDView.mm:
(-[WKPDFHUDView hitTest:]): Use WKPageProxy::cocoaView instead of fromWebPageProxy.

* UIProcess/WebURLSchemeTask.cpp:
(WebKit::WebURLSchemeTask::didPerformRedirection): Don't raise the "task stopped"
exception if it has been explicitly suppressed.
(WebKit::WebURLSchemeTask::didReceiveResponse): Ditto.
(WebKit::WebURLSchemeTask::didReceiveData): Ditto.
(WebKit::WebURLSchemeTask::didComplete): Ditto.

* UIProcess/WebURLSchemeTask.h: Added a suppressTaskStoppedExceptions function,
which we use to prevent exceptions in the case where the WKWebView was deallocated.
Since we were not able to call the delegate method in that case, the caller can't
be expected to refrain from calling methods. Eventually, clients of WKWebView could avoid this
by calling the _close method instead of relying for deallocation to do web view teardown,
but we need to promote that from SPI to API.

* UIProcess/WebPageProxy.h: Tweaked forward declarations a bit, and added one for WKWebView.
Marked the class final and use final instead of override. Added Cocoa-only cocoaView and
setCocoaView function members, and m_cocoaView data member. Also added inline implementations
but only compile them when included from an Objective-C source file.

* WebKit.xcodeproj/project.pbxproj: Removed objcSPI.h.

Source/WTF:

* wtf/spi/cocoa/objcSPI.h: Removed unnecessary #if so functions are correctly compiled for
non-Objective-C source files. Added include of <objc/objc.h> so that "id" is defined.

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
Use _close instead of WKWebView deallocation to trigger a call to stopURLSchemeTask,
since such delegate methods will intentionally no longer be delivered if triggered by deallocation.

Modified Paths

Removed Paths

Diff

Modified: trunk/Source/_javascript_Core/API/ObjcRuntimeExtras.h (274763 => 274764)


--- trunk/Source/_javascript_Core/API/ObjcRuntimeExtras.h	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/_javascript_Core/API/ObjcRuntimeExtras.h	2021-03-22 18:45:13 UTC (rev 274764)
@@ -243,8 +243,6 @@
 extern "C" {
     // Forward declare some Objective-C runtime internal methods that are not API.
     const char *_protocol_getMethodTypeEncoding(Protocol *, SEL, BOOL isRequiredMethod, BOOL isInstanceMethod);
-    id objc_initWeak(id *, id);
-    void objc_destroyWeak(id *);
     bool _Block_has_signature(void *);
     const char * _Block_signature(void *);
 }

Modified: trunk/Source/_javascript_Core/ChangeLog (274763 => 274764)


--- trunk/Source/_javascript_Core/ChangeLog	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-03-22 18:45:13 UTC (rev 274764)
@@ -1,3 +1,13 @@
+2021-03-19  Darin Adler  <da...@apple.com>
+
+        [Cocoa] Make it possible to release a WKWebView on a non-main thread without a crash due to WKScriptMessage race
+        https://bugs.webkit.org/show_bug.cgi?id=222336
+
+        Reviewed by Chris Dumez.
+
+        * API/ObjcRuntimeExtras.h: Removed declarations of objc_initWeak and objc_destroyWeak, since
+        these are already in <wtf/spi/cocoa/objcSPI.h>.
+
 2021-03-19  Mark Lam  <mark....@apple.com>
 
         BrandedStructure should keep its members alive.

Modified: trunk/Source/WTF/ChangeLog (274763 => 274764)


--- trunk/Source/WTF/ChangeLog	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WTF/ChangeLog	2021-03-22 18:45:13 UTC (rev 274764)
@@ -1,3 +1,13 @@
+2021-03-19  Darin Adler  <da...@apple.com>
+
+        [Cocoa] Make it possible to release a WKWebView on a non-main thread without a crash due to WKScriptMessage race
+        https://bugs.webkit.org/show_bug.cgi?id=222336
+
+        Reviewed by Chris Dumez.
+
+        * wtf/spi/cocoa/objcSPI.h: Removed unnecessary #if so functions are correctly compiled for
+        non-Objective-C source files. Added include of <objc/objc.h> so that "id" is defined.
+
 2021-03-19  Sam Weinig  <wei...@apple.com>
 
         Add PropertyName parameter to custom setters to allow shared implementations to do late name lookup

Modified: trunk/Source/WTF/wtf/spi/cocoa/objcSPI.h (274763 => 274764)


--- trunk/Source/WTF/wtf/spi/cocoa/objcSPI.h	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WTF/wtf/spi/cocoa/objcSPI.h	2021-03-22 18:45:13 UTC (rev 274764)
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include <objc/objc.h>
+
 #if USE(APPLE_INTERNAL_SDK)
 
 #include <objc/objc-internal.h>
@@ -36,12 +38,10 @@
 void* objc_autoreleasePoolPush(void);
 void objc_autoreleasePoolPop(void* context);
 
-#ifdef __OBJC__
 id objc_loadWeakRetained(id*);
 id objc_initWeak(id*, id);
 void objc_destroyWeak(id*);
 void objc_copyWeak(id*, id*);
 void objc_moveWeak(id*, id*);
-#endif
 
 WTF_EXTERN_C_END

Modified: trunk/Source/WebKit/ChangeLog (274763 => 274764)


--- trunk/Source/WebKit/ChangeLog	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/ChangeLog	2021-03-22 18:45:13 UTC (rev 274764)
@@ -1,3 +1,102 @@
+2021-03-19  Darin Adler  <da...@apple.com>
+
+        [Cocoa] Make it possible to release a WKWebView on a non-main thread without a crash due to WKScriptMessage race
+        https://bugs.webkit.org/show_bug.cgi?id=222336
+
+        Reviewed by Chris Dumez.
+
+        * Platform/spi/Cocoa/objcSPI.h: Removed this unused file.
+
+        * UIProcess/API/C/mac/WKPagePrivateMac.mm:
+        (WKPageGetWebView): Use WKPageProxy::cocoaView instead of fromWebPageProxy.
+        * UIProcess/API/Cocoa/WKDownload.mm:
+        (-[WKDownload webView]): Ditto.
+        * UIProcess/API/Cocoa/WKFrameInfo.mm:
+        (-[WKFrameInfo webView]): Ditto.
+
+        * UIProcess/API/Cocoa/WKUserContentController.mm:
+        (ScriptMessageHandlerDelegate::didPostMessage): Use WKPageProxy::cocoaView
+        instead of fromWebPageProxy and add null checks.
+        (ScriptMessageHandlerDelegate::didPostMessageWithAsyncReply): Ditto.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (pageToViewMap): Deleted.
+        (fromWebPageProxy): Deleted.
+        (-[WKWebView _initializeWithConfiguration:]): Use WKPageProxy::setCocoaView
+        instead of adding the page/view pair to a map.
+        (-[WKWebView dealloc]): Removed code that removed the page/view pair from the map.
+
+        * UIProcess/API/Cocoa/WKWebViewInternal.h: Removed fromWebPageProxy.
+
+        * UIProcess/API/Cocoa/_WKDownload.mm:
+        (-[_WKDownload originatingWebView]): Use WKPageProxy::cocoaView instead of fromWebPageProxy.
+        * UIProcess/API/Cocoa/_WKFrameTreeNode.mm:
+        (-[_WKFrameTreeNode webView]): Ditto.
+        * UIProcess/API/Cocoa/_WKInspector.mm:
+        (-[_WKInspector webView]): Ditto.
+        * UIProcess/API/Cocoa/_WKInspectorTesting.mm:
+        (-[_WKInspector inspectorWebView]): Ditto.
+
+        * UIProcess/Cocoa/AutomationSessionClient.mm:
+        (WebKit::AutomationSessionClient::requestSwitchToPage): Use WKPageProxy::cocoaView
+        instead of fromWebPageProxy and add a null check.
+        (WebKit::AutomationSessionClient::requestHideWindowOfPage): Ditto.
+        (WebKit::AutomationSessionClient::requestRestoreWindowOfPage): Ditto.
+        (WebKit::AutomationSessionClient::requestMaximizeWindowOfPage): Ditto.
+        (WebKit::AutomationSessionClient::isShowingJavaScriptDialogOnPage): Ditto.
+        (WebKit::AutomationSessionClient::dismissCurrentJavaScriptDialogOnPage): Ditto.
+        (WebKit::AutomationSessionClient::acceptCurrentJavaScriptDialogOnPage): Ditto.
+        (WebKit::AutomationSessionClient::messageOfCurrentJavaScriptDialogOnPage): Ditto.
+        (WebKit::AutomationSessionClient::setUserInputForCurrentJavaScriptPromptOnPage): Ditto.
+        (WebKit::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage): Ditto.
+        (WebKit::AutomationSessionClient::currentPresentationOfPage): Ditto.
+
+        * UIProcess/Cocoa/MediaPermissionUtilities.mm:
+        (WebKit::alertForPermission): Use WKPageProxy::cocoaView instead of fromWebPageProxy.
+
+        * UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm:
+        (WebKit::PopUpSOAuthorizationSession::abortInternal): Added a null check since
+        initSecretWebView is no longer guaranteed to allocate m_secretWebView in the case
+        where the WKWebView is nil.
+        (WebKit::PopUpSOAuthorizationSession::completeInternal): Ditto.
+        (WebKit::PopUpSOAuthorizationSession::initSecretWebView): Use WKPageProxy::cocoaView
+        instead of fromWebPageProxy and added a null check.
+
+        * UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm:
+        (WebKit::SOAuthorizationSession::continueStartAfterDecidePolicy): Use WKPageProxy::cocoaView
+        instead of fromWebPageProxy.
+
+        * UIProcess/Cocoa/WebURLSchemeHandlerCocoa.mm:
+        (WebKit::WebURLSchemeHandlerCocoa::platformStartTask): Use WKPageProxy::cocoaView
+        instead of fromWebPageProxy and added a null check.
+        (WebKit::WebURLSchemeHandlerCocoa::platformStopTask): Ditto. Also call the
+        new suppressTaskStoppedExceptions if we are unable to call the delegate method due to
+        the WKWebView already being nil.
+
+        * UIProcess/PDF/WKPDFHUDView.mm:
+        (-[WKPDFHUDView hitTest:]): Use WKPageProxy::cocoaView instead of fromWebPageProxy.
+
+        * UIProcess/WebURLSchemeTask.cpp:
+        (WebKit::WebURLSchemeTask::didPerformRedirection): Don't raise the "task stopped"
+        exception if it has been explicitly suppressed.
+        (WebKit::WebURLSchemeTask::didReceiveResponse): Ditto.
+        (WebKit::WebURLSchemeTask::didReceiveData): Ditto.
+        (WebKit::WebURLSchemeTask::didComplete): Ditto.
+
+        * UIProcess/WebURLSchemeTask.h: Added a suppressTaskStoppedExceptions function,
+        which we use to prevent exceptions in the case where the WKWebView was deallocated.
+        Since we were not able to call the delegate method in that case, the caller can't
+        be expected to refrain from calling methods. Eventually, clients of WKWebView could avoid this
+        by calling the _close method instead of relying for deallocation to do web view teardown,
+        but we need to promote that from SPI to API.
+
+        * UIProcess/WebPageProxy.h: Tweaked forward declarations a bit, and added one for WKWebView.
+        Marked the class final and use final instead of override. Added Cocoa-only cocoaView and
+        setCocoaView function members, and m_cocoaView data member. Also added inline implementations
+        but only compile them when included from an Objective-C source file.
+
+        * WebKit.xcodeproj/project.pbxproj: Removed objcSPI.h.
+
 2021-03-22  Youenn Fablet  <you...@apple.com>
 
         Implement RTCDataChannel transfer out of process

Deleted: trunk/Source/WebKit/Platform/spi/Cocoa/objcSPI.h (274763 => 274764)


--- trunk/Source/WebKit/Platform/spi/Cocoa/objcSPI.h	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/objcSPI.h	2021-03-22 18:45:13 UTC (rev 274764)
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if USE(APPLE_INTERNAL_SDK)
-
-#import <objc/objc-internal.h>
-
-#endif
-
-OBJC_EXPORT id _objc_rootRetain(id obj);
-OBJC_EXPORT bool _objc_rootReleaseWasZero(id obj);
-OBJC_EXPORT bool _objc_rootTryRetain(id obj);
-OBJC_EXPORT bool _objc_rootIsDeallocating(id obj);
-OBJC_EXPORT id _objc_rootAutorelease(id obj);
-OBJC_EXPORT uintptr_t _objc_rootRetainCount(id obj);
-OBJC_EXPORT void _objc_rootDealloc(id obj);

Modified: trunk/Source/WebKit/UIProcess/API/C/mac/WKPagePrivateMac.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/C/mac/WKPagePrivateMac.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/C/mac/WKPagePrivateMac.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -155,9 +155,7 @@
 
 WKWebView *WKPageGetWebView(WKPageRef page)
 {
-    if (!page)
-        return nil;
-    return fromWebPageProxy(*WebKit::toImpl(page));
+    return page ? WebKit::toImpl(page)->cocoaView().autorelease() : nil;
 }
 
 #if PLATFORM(MAC)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -33,6 +33,7 @@
 #import "WKNSData.h"
 #import "WKNSURLAuthenticationChallenge.h"
 #import "WKWebViewInternal.h"
+#import "WebPageProxy.h"
 #import <Foundation/Foundation.h>
 #import <WebCore/WebCoreObjCExtras.h>
 #import <wtf/WeakObjCPtr.h>
@@ -196,10 +197,8 @@
 
 - (WKWebView *)webView
 {
-    auto* page = _download->originatingPage();
-    if (!page)
-        return nil;
-    return fromWebPageProxy(*page);
+    auto page = _download->originatingPage();
+    return page ? page->cocoaView().autorelease() : nil;
 }
 
 - (id <WKDownloadDelegate>)delegate

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKFrameInfo.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKFrameInfo.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKFrameInfo.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -67,9 +67,8 @@
 
 - (WKWebView *)webView
 {
-    if (WebKit::WebPageProxy* page = _frameInfo->page())
-        return retainPtr(fromWebPageProxy(*page)).autorelease();
-    return nil;
+    auto page = _frameInfo->page();
+    return page ? page->cocoaView().autorelease() : nil;
 }
 
 - (id)copyWithZone:(NSZone *)zone

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentController.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentController.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUserContentController.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -145,9 +145,12 @@
     void didPostMessage(WebKit::WebPageProxy& page, WebKit::FrameInfoData&& frameInfoData, API::ContentWorld& world, WebCore::SerializedScriptValue& serializedScriptValue) final
     {
         @autoreleasepool {
+            auto webView = page.cocoaView();
+            if (!webView)
+                return;
             RetainPtr<WKFrameInfo> frameInfo = wrapper(API::FrameInfo::create(WTFMove(frameInfoData), &page));
             id body = API::SerializedScriptValue::deserialize(serializedScriptValue, 0);
-            auto message = adoptNS([[WKScriptMessage alloc] _initWithBody:body webView:fromWebPageProxy(page) frameInfo:frameInfo.get() name:m_name.get() world:wrapper(world)]);
+            auto message = adoptNS([[WKScriptMessage alloc] _initWithBody:body webView:webView.get() frameInfo:frameInfo.get() name:m_name.get() world:wrapper(world)]);
         
             [(id<WKScriptMessageHandler>)m_handler.get() userContentController:m_controller.get() didReceiveScriptMessage:message.get()];
         }
@@ -162,6 +165,12 @@
     {
         ASSERT(m_supportsAsyncReply);
 
+        auto webView = page.cocoaView();
+        if (!webView) {
+            replyHandler(nullptr, "The WKWebView was deallocated before the message was delivered"_s);
+            return;
+        }
+
         auto finalizer = [](Function<void(API::SerializedScriptValue*, const String&)>& function) {
             function(nullptr, "WKWebView API client did not respond to this postMessage"_s);
         };
@@ -170,7 +179,7 @@
         @autoreleasepool {
             RetainPtr<WKFrameInfo> frameInfo = wrapper(API::FrameInfo::create(WTFMove(frameInfoData), &page));
             id body = API::SerializedScriptValue::deserialize(serializedScriptValue, 0);
-            auto message = adoptNS([[WKScriptMessage alloc] _initWithBody:body webView:fromWebPageProxy(page) frameInfo:frameInfo.get() name:m_name.get() world:wrapper(world)]);
+            auto message = adoptNS([[WKScriptMessage alloc] _initWithBody:body webView:webView.get() frameInfo:frameInfo.get() name:m_name.get() world:wrapper(world)]);
 
             [(id<WKScriptMessageHandlerWithReply>)m_handler.get() userContentController:m_controller.get() didReceiveScriptMessage:message.get() replyHandler:^(id result, NSString *errorMessage) {
                 if (errorMessage) {

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -197,17 +197,6 @@
 static const uint32_t firstSDKVersionWithLinkPreviewEnabledByDefault = 0xA0000;
 #endif // PLATFORM(IOS_FAMILY)
 
-static HashMap<WebKit::WebPageProxy*, __unsafe_unretained WKWebView *>& pageToViewMap()
-{
-    static NeverDestroyed<HashMap<WebKit::WebPageProxy*, __unsafe_unretained WKWebView *>> map;
-    return map;
-}
-
-WKWebView* fromWebPageProxy(WebKit::WebPageProxy& page)
-{
-    return pageToViewMap().get(&page);
-}
-
 RetainPtr<NSError> nsErrorFromExceptionDetails(const WebCore::ExceptionDetails& details)
 {
     auto userInfo = adoptNS([[NSMutableDictionary alloc] init]);
@@ -440,7 +429,7 @@
     for (auto& pair : pageConfiguration->urlSchemeHandlers())
         _page->setURLSchemeHandlerForScheme(WebKit::WebURLSchemeHandlerCocoa::create(static_cast<WebKit::WebURLSchemeHandlerCocoa&>(pair.value.get()).apiHandler()), pair.key);
 
-    pageToViewMap().add(_page.get(), self);
+    _page->setCocoaView(self);
 
     [WebViewVisualIdentificationOverlay installForWebViewIfNeeded:self kind:@"WKWebView" deprecated:NO];
 
@@ -449,7 +438,7 @@
     _timeOfRequestForVisibleContentRectUpdate = timeNow;
     _timeOfLastVisibleContentRectUpdate = timeNow;
     _timeOfFirstVisibleContentRectUpdateWithPendingCommit = timeNow;
-#endif // PLATFORM(IOS_FAMILY)
+#endif
 }
 
 - (void)_setupPageConfiguration:(Ref<API::PageConfiguration>&)pageConfiguration
@@ -643,9 +632,6 @@
     CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), (CFStringRef)[NSString stringWithUTF8String:kGSEventHardwareKeyboardAvailabilityChangedNotification], nullptr);
 #endif
 
-    if (_page)
-        pageToViewMap().remove(_page.get());
-
     [super dealloc];
 }
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h	2021-03-22 18:45:13 UTC (rev 274764)
@@ -283,7 +283,6 @@
 
 @end
 
-WKWebView* fromWebPageProxy(WebKit::WebPageProxy&);
 RetainPtr<NSError> nsErrorFromExceptionDetails(const WebCore::ExceptionDetails&);
 
 #if ENABLE(FULLSCREEN_API) && PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -84,9 +84,8 @@
 
 - (WKWebView *)originatingWebView
 {
-    if (auto* originatingPage = _download->_download->originatingPage())
-        return retainPtr(fromWebPageProxy(*originatingPage)).autorelease();
-    return nil;
+    auto page = _download->_download->originatingPage();
+    return page ? page->cocoaView().autorelease() : nil;
 }
 
 -(NSArray<NSURL *> *)redirectChain

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -27,6 +27,7 @@
 
 #import "WKSecurityOriginInternal.h"
 #import "WKWebViewInternal.h"
+#import "WebPageProxy.h"
 #import "_WKFrameHandleInternal.h"
 #import "_WKFrameTreeNodeInternal.h"
 #import <WebCore/WebCoreObjCExtras.h>
@@ -61,7 +62,7 @@
 
 - (WKWebView *)webView
 {
-    return retainPtr(fromWebPageProxy(_node->page())).autorelease();
+    return _node->page().cocoaView().autorelease();
 }
 
 - (NSArray<_WKFrameTreeNode *> *)childFrames

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspector.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspector.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspector.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -66,9 +66,8 @@
 
 - (WKWebView *)webView
 {
-    if (auto* page = _inspector->inspectedPage())
-        return fromWebPageProxy(*page);
-    return nil;
+    auto page = _inspector->inspectedPage();
+    return page ? page->cocoaView().autorelease() : nil;
 }
 
 - (BOOL)isConnected

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorTesting.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorTesting.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorTesting.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -26,6 +26,7 @@
 #import "config.h"
 
 #import "WKWebViewInternal.h"
+#import "WebPageProxy.h"
 #import "_WKInspectorInternal.h"
 #import "_WKInspectorPrivateForTesting.h"
 
@@ -41,9 +42,8 @@
 
 - (WKWebView *)inspectorWebView
 {
-    if (auto* page = _inspector->inspectorPage())
-        return fromWebPageProxy(*page);
-    return nil;
+    auto page = _inspector->inspectorPage();
+    return page ? page->cocoaView().autorelease() : nil;
 }
 
 - (void)_openURLExternallyForTesting:(NSURL *)url useFrontendAPI:(BOOL)useFrontendAPI

Modified: trunk/Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -83,8 +83,8 @@
 
 void AutomationSessionClient::requestSwitchToPage(WebAutomationSession& session, WebPageProxy& page, CompletionHandler<void()>&& completionHandler)
 {
-    if (m_delegateMethods.requestSwitchToWebView)
-        [m_delegate.get() _automationSession:wrapper(session) requestSwitchToWebView:fromWebPageProxy(page) completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.requestSwitchToWebView)
+        [m_delegate.get() _automationSession:wrapper(session) requestSwitchToWebView:webView.get() completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
     else
         completionHandler();
 }
@@ -91,8 +91,8 @@
 
 void AutomationSessionClient::requestHideWindowOfPage(WebAutomationSession& session, WebPageProxy& page, CompletionHandler<void()>&& completionHandler)
 {
-    if (m_delegateMethods.requestHideWindowOfWebView)
-        [m_delegate.get() _automationSession:wrapper(session) requestHideWindowOfWebView:fromWebPageProxy(page) completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.requestHideWindowOfWebView)
+        [m_delegate.get() _automationSession:wrapper(session) requestHideWindowOfWebView:webView.get() completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
     else
         completionHandler();
 }
@@ -99,8 +99,8 @@
 
 void AutomationSessionClient::requestRestoreWindowOfPage(WebAutomationSession& session, WebPageProxy& page, CompletionHandler<void()>&& completionHandler)
 {
-    if (m_delegateMethods.requestRestoreWindowOfWebView)
-        [m_delegate.get() _automationSession:wrapper(session) requestRestoreWindowOfWebView:fromWebPageProxy(page) completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.requestRestoreWindowOfWebView)
+        [m_delegate.get() _automationSession:wrapper(session) requestRestoreWindowOfWebView:webView.get() completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
     else
         completionHandler();
 }
@@ -107,8 +107,8 @@
 
 void AutomationSessionClient::requestMaximizeWindowOfPage(WebAutomationSession& session, WebPageProxy& page, CompletionHandler<void()>&& completionHandler)
 {
-    if (m_delegateMethods.requestMaximizeWindowOfWebView)
-        [m_delegate.get() _automationSession:wrapper(session) requestMaximizeWindowOfWebView:fromWebPageProxy(page) completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.requestMaximizeWindowOfWebView)
+        [m_delegate.get() _automationSession:wrapper(session) requestMaximizeWindowOfWebView:webView.get() completionHandler:makeBlockPtr(WTFMove(completionHandler)).get()];
     else
         completionHandler();
 }
@@ -115,8 +115,8 @@
 
 bool AutomationSessionClient::isShowingJavaScriptDialogOnPage(WebAutomationSession& session, WebPageProxy& page)
 {
-    if (m_delegateMethods.isShowingJavaScriptDialogForWebView)
-        return [m_delegate.get() _automationSession:wrapper(session) isShowingJavaScriptDialogForWebView:fromWebPageProxy(page)];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.isShowingJavaScriptDialogForWebView)
+        return [m_delegate.get() _automationSession:wrapper(session) isShowingJavaScriptDialogForWebView:webView.get()];
     
     return false;
 }
@@ -123,20 +123,20 @@
 
 void AutomationSessionClient::dismissCurrentJavaScriptDialogOnPage(WebAutomationSession& session, WebPageProxy& page)
 {
-    if (m_delegateMethods.dismissCurrentJavaScriptDialogForWebView)
-        [m_delegate.get() _automationSession:wrapper(session) dismissCurrentJavaScriptDialogForWebView:fromWebPageProxy(page)];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.dismissCurrentJavaScriptDialogForWebView)
+        [m_delegate.get() _automationSession:wrapper(session) dismissCurrentJavaScriptDialogForWebView:webView.get()];
 }
 
 void AutomationSessionClient::acceptCurrentJavaScriptDialogOnPage(WebAutomationSession& session, WebPageProxy& page)
 {
-    if (m_delegateMethods.acceptCurrentJavaScriptDialogForWebView)
-        [m_delegate.get() _automationSession:wrapper(session) acceptCurrentJavaScriptDialogForWebView:fromWebPageProxy(page)];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.acceptCurrentJavaScriptDialogForWebView)
+        [m_delegate.get() _automationSession:wrapper(session) acceptCurrentJavaScriptDialogForWebView:webView.get()];
 }
 
 String AutomationSessionClient::messageOfCurrentJavaScriptDialogOnPage(WebAutomationSession& session, WebPageProxy& page)
 {
-    if (m_delegateMethods.messageOfCurrentJavaScriptDialogForWebView)
-        return [m_delegate.get() _automationSession:wrapper(session) messageOfCurrentJavaScriptDialogForWebView:fromWebPageProxy(page)];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.messageOfCurrentJavaScriptDialogForWebView)
+        return [m_delegate.get() _automationSession:wrapper(session) messageOfCurrentJavaScriptDialogForWebView:webView.get()];
 
     return String();
 }
@@ -143,8 +143,8 @@
 
 void AutomationSessionClient::setUserInputForCurrentJavaScriptPromptOnPage(WebAutomationSession& session, WebPageProxy& page, const String& value)
 {
-    if (m_delegateMethods.setUserInputForCurrentJavaScriptPromptForWebView)
-        [m_delegate.get() _automationSession:wrapper(session) setUserInput:value forCurrentJavaScriptDialogForWebView:fromWebPageProxy(page)];
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.setUserInputForCurrentJavaScriptPromptForWebView)
+        [m_delegate.get() _automationSession:wrapper(session) setUserInput:value forCurrentJavaScriptDialogForWebView:webView.get()];
 }
 
 static Optional<API::AutomationSessionClient::_javascript_DialogType> toImpl(_WKAutomationSessionJavaScriptDialogType type)
@@ -173,8 +173,8 @@
 
 Optional<API::AutomationSessionClient::_javascript_DialogType> AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage(WebAutomationSession& session, WebPageProxy& page)
 {
-    if (m_delegateMethods.typeOfCurrentJavaScriptDialogForWebView)
-        return toImpl([m_delegate.get() _automationSession:wrapper(session) typeOfCurrentJavaScriptDialogForWebView:fromWebPageProxy(page)]);
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.typeOfCurrentJavaScriptDialogForWebView)
+        return toImpl([m_delegate.get() _automationSession:wrapper(session) typeOfCurrentJavaScriptDialogForWebView:webView.get()]);
 
     return API::AutomationSessionClient::_javascript_DialogType::Prompt;
 }
@@ -181,8 +181,8 @@
 
 API::AutomationSessionClient::BrowsingContextPresentation AutomationSessionClient::currentPresentationOfPage(WebAutomationSession& session, WebPageProxy& page)
 {
-    if (m_delegateMethods.currentPresentationForWebView)
-        return toImpl([m_delegate.get() _automationSession:wrapper(session) currentPresentationForWebView:fromWebPageProxy(page)]);
+    if (auto webView = page.cocoaView(); webView && m_delegateMethods.currentPresentationForWebView)
+        return toImpl([m_delegate.get() _automationSession:wrapper(session) currentPresentationForWebView:webView.get()]);
 
     return API::AutomationSessionClient::BrowsingContextPresentation::Window;
 }

Modified: trunk/Source/WebKit/UIProcess/Cocoa/MediaPermissionUtilities.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/Cocoa/MediaPermissionUtilities.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/Cocoa/MediaPermissionUtilities.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -185,7 +185,7 @@
     }
 #endif
 
-    auto *webView = fromWebPageProxy(page);
+    auto webView = page.cocoaView();
     if (!webView) {
         completionHandler(false);
         return;
@@ -208,7 +208,7 @@
     button.keyEquivalent = @"";
     button = [alert addButtonWithTitle:doNotAllowButtonString];
     button.keyEquivalent = @"\E";
-    [alert beginSheetModalForWindow:webView.window completionHandler:[completionBlock](NSModalResponse returnCode) {
+    [alert beginSheetModalForWindow:[webView window] completionHandler:[completionBlock](NSModalResponse returnCode) {
         auto shouldAllow = returnCode == NSAlertFirstButtonReturn;
         completionBlock(shouldAllow);
     }];
@@ -225,7 +225,7 @@
     [alert addAction:doNotAllowAction];
     [alert addAction:allowAction];
 
-    [[UIViewController _viewControllerForFullScreenPresentationFromView:webView] presentViewController:alert animated:YES completion:nil];
+    [[UIViewController _viewControllerForFullScreenPresentationFromView:webView.get()] presentViewController:alert animated:YES completion:nil];
 #endif
 }
 

Modified: trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/PopUpSOAuthorizationSession.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -129,6 +129,11 @@
     }
 
     initSecretWebView();
+    if (!m_secretWebView) {
+        m_newPageCallback(nullptr);
+        return;
+    }
+
     m_newPageCallback(m_secretWebView->_page.get());
     [m_secretWebView evaluateJavaScript: @"window.close()" completionHandler:nil];
 }
@@ -141,6 +146,11 @@
     }
 
     initSecretWebView();
+    if (!m_secretWebView) {
+        fallBackToWebPathInternal();
+        return;
+    }
+
     m_newPageCallback(m_secretWebView->_page.get());
     [m_secretWebView loadData:data MIMEType:@"text/html" characterEncodingName:@"UTF-8" baseURL:response.url()];
 }
@@ -160,9 +170,11 @@
 void PopUpSOAuthorizationSession::initSecretWebView()
 {
     ASSERT(page());
-    auto initiatorWebView = fromWebPageProxy(*page());
-    auto configuration = adoptNS([initiatorWebView.configuration copy]);
-    [configuration _setRelatedWebView:initiatorWebView];
+    auto initiatorWebView = page()->cocoaView();
+    if (!initiatorWebView)
+        return;
+    auto configuration = adoptNS([[initiatorWebView configuration] copy]);
+    [configuration _setRelatedWebView:initiatorWebView.get()];
     m_secretWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
 
     m_secretDelegate = adoptNS([[WKSOSecretDelegate alloc] initWithSession:this]);

Modified: trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationSession.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -182,7 +182,7 @@
     [m_soAuthorization setAuthorizationOptions:authorizationOptions];
 
 #if PLATFORM(IOS)
-    if (![fromWebPageProxy(*m_page).UIDelegate respondsToSelector:@selector(_presentingViewControllerForWebView:)])
+    if (![[m_page->cocoaView() UIDelegate] respondsToSelector:@selector(_presentingViewControllerForWebView:)])
         [m_soAuthorization setEnableEmbeddedAuthorizationViewController:NO];
 #endif
 

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebURLSchemeHandlerCocoa.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebURLSchemeHandlerCocoa.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebURLSchemeHandlerCocoa.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -35,7 +35,6 @@
 #import <wtf/RunLoop.h>
 
 namespace WebKit {
-using namespace WebCore;
 
 Ref<WebURLSchemeHandlerCocoa> WebURLSchemeHandlerCocoa::create(id <WKURLSchemeHandler> apiHandler)
 {
@@ -52,7 +51,8 @@
     auto result = m_apiTasks.add(task.identifier(), API::URLSchemeTask::create(task));
     ASSERT(result.isNewEntry);
 
-    [m_apiHandler.get() webView:fromWebPageProxy(page) startURLSchemeTask:wrapper(result.iterator->value.get())];
+    if (auto webView = page.cocoaView())
+        [m_apiHandler.get() webView:webView.get() startURLSchemeTask:wrapper(result.iterator->value.get())];
 }
 
 void WebURLSchemeHandlerCocoa::platformStopTask(WebPageProxy& page, WebURLSchemeTask& task)
@@ -61,7 +61,10 @@
     if (iterator == m_apiTasks.end())
         return;
 
-    [m_apiHandler.get() webView:fromWebPageProxy(page) stopURLSchemeTask:wrapper(iterator->value.get())];
+    if (auto webView = page.cocoaView())
+        [m_apiHandler.get() webView:webView.get() stopURLSchemeTask:wrapper(iterator->value.get())];
+    else
+        task.suppressTaskStoppedExceptions();
 
     m_apiTasks.remove(iterator);
 }

Modified: trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.mm (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -163,11 +163,8 @@
 
 - (NSView *)hitTest:(NSPoint)point
 {
-    if (_page)
-        return fromWebPageProxy(*_page);
-
-    ASSERT_NOT_REACHED();
-    return self;
+    ASSERT(_page);
+    return _page ? _page->cocoaView().autorelease() : self;
 }
 
 - (void)mouseMoved:(NSEvent *)event

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-03-22 18:45:13 UTC (rev 274764)
@@ -138,11 +138,6 @@
 #include "EndowmentStateTracker.h"
 #endif
 
-OBJC_CLASS NSMenu;
-OBJC_CLASS NSTextAlternatives;
-OBJC_CLASS NSView;
-OBJC_CLASS _WKRemoteObjectRegistry;
-
 #if ENABLE(DRAG_SUPPORT)
 #include <WebCore/DragActions.h>
 #endif
@@ -154,6 +149,7 @@
 #if PLATFORM(COCOA)
 #include "DynamicViewportSizeUpdate.h"
 #include "RemoteLayerTreeNode.h"
+#include <wtf/WeakObjCPtr.h>
 #endif
 
 #if HAVE(TOUCH_BAR)
@@ -219,10 +215,19 @@
 class FormDataReference;
 class SharedBufferCopy;
 }
+
+#if PLATFORM(COCOA)
 OBJC_CLASS NSFileWrapper;
+OBJC_CLASS NSMenu;
+OBJC_CLASS NSTextAlternatives;
+OBJC_CLASS NSView;
 OBJC_CLASS WKQLThumbnailLoadOperation;
+OBJC_CLASS WKWebView;
+OBJC_CLASS _WKRemoteObjectRegistry;
+#endif
 
 namespace WebCore {
+
 class AuthenticationChallenge;
 class CertificateInfo;
 class Cursor;
@@ -294,6 +299,7 @@
 
 template<typename> class RectEdges;
 using FloatBoxExtent = RectEdges<float>;
+
 }
 
 #if PLATFORM(GTK)
@@ -313,7 +319,7 @@
 #endif
 
 namespace WebKit {
-struct AppBoundNavigationTestingData;
+
 class AudioSessionRoutingArbitratorProxy;
 class DrawingAreaProxy;
 class GamepadData;
@@ -359,7 +365,7 @@
 class WebWheelEventCoalescer;
 class WebsiteDataStore;
 
-struct WebBackForwardListCounts;
+struct AppBoundNavigationTestingData;
 struct ColorSpaceData;
 struct DataDetectionResult;
 struct DocumentEditingContext;
@@ -380,13 +386,14 @@
 struct PrintInfo;
 struct PDFContextMenu;
 struct ResourceLoadInfo;
+struct URLSchemeTaskParameters;
+struct UserMessage;
 struct WebAutocorrectionData;
+struct WebBackForwardListCounts;
 struct WebHitTestResultData;
 struct WebNavigationDataStore;
 struct WebPopupItem;
 struct WebSpeechSynthesisVoice;
-struct URLSchemeTaskParameters;
-struct UserMessage;
 
 enum class NegotiatedLegacyTLS : bool;
 enum class ProcessSwapRequestedByClient : bool;
@@ -414,7 +421,7 @@
 
 using SpellDocumentTag = int64_t;
 
-class WebPageProxy : public API::ObjectImpl<API::Object::Type::Page>
+class WebPageProxy final : public API::ObjectImpl<API::Object::Type::Page>
 #if ENABLE(INPUT_TYPE_COLOR)
     , public WebColorPicker::Client
 #endif
@@ -1358,7 +1365,7 @@
 #endif
 
     // WebPopupMenuProxy::Client
-    NativeWebMouseEvent* currentlyProcessedMouseDownEvent() override;
+    NativeWebMouseEvent* currentlyProcessedMouseDownEvent() final;
 
     void setSuppressVisibilityUpdates(bool flag);
     bool suppressVisibilityUpdates() { return m_suppressVisibilityUpdates; }
@@ -1644,8 +1651,8 @@
 #if HAVE(QUICKLOOK_THUMBNAILING)
     void updateAttachmentIcon(const String&, const RefPtr<ShareableBitmap>&);
     void requestThumbnailWithPath(const String&, const String&);
-    void requestThumbnailWithFileWrapper(NSFileWrapper*, const String&);
-    void requestThumbnailWithOperation(WKQLThumbnailLoadOperation*);
+    void requestThumbnailWithFileWrapper(NSFileWrapper *, const String&);
+    void requestThumbnailWithOperation(WKQLThumbnailLoadOperation *);
 #endif
     enum class ShouldUpdateAttachmentAttributes : bool { No, Yes };
     ShouldUpdateAttachmentAttributes willUpdateAttachmentAttributes(const API::Attachment&);
@@ -1736,8 +1743,8 @@
 
     // IPC::MessageReceiver
     // Implemented in generated WebPageProxyMessageReceiver.cpp
-    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
-    bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) override;
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
+    bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) final;
 
     void requestStorageSpace(WebCore::FrameIdentifier, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, WTF::CompletionHandler<void(uint64_t)>&&);
 
@@ -1806,8 +1813,11 @@
     void grantAccessToCurrentPasteboardData(const String& pasteboardName);
 #endif
 
+#if PLATFORM(MAC)
+    NSMenu *platformActiveContextMenu() const;
+#endif
+
 #if ENABLE(CONTEXT_MENUS)
-    NSMenu *platformActiveContextMenu() const;
     void platformDidSelectItemFromActiveContextMenu(const WebContextMenuItemData&);
 #endif
 
@@ -1879,12 +1889,13 @@
     void lastNavigationWasAppBound(CompletionHandler<void(bool)>&&);
     void appBoundNavigationData(CompletionHandler<void(const AppBoundNavigationTestingData&)>&&);
     void clearAppBoundNavigationData(CompletionHandler<void()>&&);
-#endif
 
-#if PLATFORM(COCOA)
     NSDictionary *contentsOfUserInterfaceItem(NSString *userInterfaceItem);
-#endif // PLATFORM(COCOA)
 
+    RetainPtr<WKWebView> cocoaView();
+    void setCocoaView(WKWebView *);
+#endif
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
     void platformInitialize();
@@ -1913,15 +1924,15 @@
     void setUserAgent(String&&);
 
     // IPC::MessageSender
-    bool sendMessage(UniqueRef<IPC::Encoder>&&, OptionSet<IPC::SendOption>, Optional<std::pair<CompletionHandler<void(IPC::Decoder*)>, uint64_t>>&&) override;
-    IPC::Connection* messageSenderConnection() const override;
-    uint64_t messageSenderDestinationID() const override;
+    bool sendMessage(UniqueRef<IPC::Encoder>&&, OptionSet<IPC::SendOption>, Optional<std::pair<CompletionHandler<void(IPC::Decoder*)>, uint64_t>>&&) final;
+    IPC::Connection* messageSenderConnection() const final;
+    uint64_t messageSenderDestinationID() const final;
 
     // WebPopupMenuProxy::Client
-    void valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex) override;
-    void setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index) override;
+    void valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex) final;
+    void setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index) final;
 #if PLATFORM(GTK)
-    void failedToShowPopupMenu() override;
+    void failedToShowPopupMenu() final;
 #endif
 
 #if ENABLE(POINTER_LOCK)
@@ -2087,8 +2098,8 @@
 
 #if ENABLE(INPUT_TYPE_COLOR)
     void showColorPicker(const WebCore::Color& initialColor, const WebCore::IntRect&, Vector<WebCore::Color>&&);
-    void didChooseColor(const WebCore::Color&) override;
-    void didEndColorPicker() override;
+    void didChooseColor(const WebCore::Color&) final;
+    void didEndColorPicker() final;
 #endif
 
 #if ENABLE(DATALIST_ELEMENT)
@@ -2389,13 +2400,13 @@
 #endif
 
 #if ENABLE(SPEECH_SYNTHESIS)
-    void didStartSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
-    void didFinishSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
-    void didPauseSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
-    void didResumeSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
-    void speakingErrorOccurred(WebCore::PlatformSpeechSynthesisUtterance&) override;
-    void boundaryEventOccurred(WebCore::PlatformSpeechSynthesisUtterance&, WebCore::SpeechBoundary, unsigned charIndex) override;
-    void voicesDidChange() override;
+    void didStartSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) final;
+    void didFinishSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) final;
+    void didPauseSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) final;
+    void didResumeSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) final;
+    void speakingErrorOccurred(WebCore::PlatformSpeechSynthesisUtterance&) final;
+    void boundaryEventOccurred(WebCore::PlatformSpeechSynthesisUtterance&, WebCore::SpeechBoundary, unsigned charIndex) final;
+    void voicesDidChange() final;
 
     struct SpeechSynthesisData;
     SpeechSynthesisData& speechSynthesisData();
@@ -2474,6 +2485,10 @@
 
     RefPtr<WebInspectorProxy> m_inspector;
 
+#if PLATFORM(COCOA)
+    WeakObjCPtr<WKWebView> m_cocoaView;
+#endif
+
 #if ENABLE(FULLSCREEN_API)
     std::unique_ptr<WebFullScreenManagerProxy> m_fullScreenManager;
     std::unique_ptr<API::FullscreenClient> m_fullscreenClient;
@@ -2945,4 +2960,18 @@
 #endif
 };
 
+#ifdef __OBJC__
+
+inline RetainPtr<WKWebView> WebPageProxy::cocoaView()
+{
+    return m_cocoaView.get();
+}
+
+inline void WebPageProxy::setCocoaView(WKWebView *view)
+{
+    m_cocoaView = view;
+}
+
+#endif
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebURLSchemeTask.cpp (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/WebURLSchemeTask.cpp	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/WebURLSchemeTask.cpp	2021-03-22 18:45:13 UTC (rev 274764)
@@ -65,7 +65,7 @@
     ASSERT(RunLoop::isMain());
 
     if (m_stopped)
-        return ExceptionType::TaskAlreadyStopped;
+        return m_shouldSuppressTaskStoppedExceptions ? ExceptionType::None : ExceptionType::TaskAlreadyStopped;
     
     if (m_completed)
         return ExceptionType::CompleteAlreadyCalled;
@@ -94,7 +94,7 @@
     ASSERT(RunLoop::isMain());
 
     if (m_stopped)
-        return ExceptionType::TaskAlreadyStopped;
+        return m_shouldSuppressTaskStoppedExceptions ? ExceptionType::None : ExceptionType::TaskAlreadyStopped;
 
     if (m_completed)
         return ExceptionType::CompleteAlreadyCalled;
@@ -118,7 +118,7 @@
     ASSERT(RunLoop::isMain());
 
     if (m_stopped)
-        return ExceptionType::TaskAlreadyStopped;
+        return m_shouldSuppressTaskStoppedExceptions ? ExceptionType::None : ExceptionType::TaskAlreadyStopped;
 
     if (m_completed)
         return ExceptionType::CompleteAlreadyCalled;
@@ -145,7 +145,7 @@
     ASSERT(RunLoop::isMain());
 
     if (m_stopped)
-        return ExceptionType::TaskAlreadyStopped;
+        return m_shouldSuppressTaskStoppedExceptions ? ExceptionType::None : ExceptionType::TaskAlreadyStopped;
 
     if (m_completed)
         return ExceptionType::CompleteAlreadyCalled;

Modified: trunk/Source/WebKit/UIProcess/WebURLSchemeTask.h (274763 => 274764)


--- trunk/Source/WebKit/UIProcess/WebURLSchemeTask.h	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/UIProcess/WebURLSchemeTask.h	2021-03-22 18:45:13 UTC (rev 274764)
@@ -86,6 +86,8 @@
     void stop();
     void pageDestroyed();
 
+    void suppressTaskStoppedExceptions() { m_shouldSuppressTaskStoppedExceptions = true; }
+
 private:
     WebURLSchemeTask(WebURLSchemeHandler&, WebPageProxy&, WebProcessProxy&, WebCore::PageIdentifier, URLSchemeTaskParameters&&, SyncLoadCompletionHandler&&);
 
@@ -103,7 +105,8 @@
     bool m_responseSent { false };
     bool m_dataSent { false };
     bool m_completed { false };
-    
+    bool m_shouldSuppressTaskStoppedExceptions { false };
+
     SyncLoadCompletionHandler m_syncCompletionHandler;
     WebCore::ResourceResponse m_syncResponse;
     RefPtr<WebCore::SharedBuffer> m_syncData;

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (274763 => 274764)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-03-22 18:45:13 UTC (rev 274764)
@@ -877,7 +877,6 @@
 		37A709A71E3EA0FD00CA5969 /* WKDataDetectorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 37A709A61E3EA0FD00CA5969 /* WKDataDetectorTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		37A709A91E3EA40C00CA5969 /* WKDataDetectorTypesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 37A709A81E3EA40C00CA5969 /* WKDataDetectorTypesInternal.h */; };
 		37B0D1841C1E499A00D40D64 /* PluginProcessShim.dylib in Copy Shims */ = {isa = PBXBuildFile; fileRef = 1AC25FB012A48EA700BD2671 /* PluginProcessShim.dylib */; };
-		37B47E2D1D64DB76005F4EFF /* objcSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 37B47E2C1D64DB76005F4EFF /* objcSPI.h */; };
 		37B5045219EEF31300CE2CF8 /* WKErrorPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 37B5045119EEF31300CE2CF8 /* WKErrorPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		37BEC4DD1948FC6A008B4286 /* WebCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1AA1C79A100E7FC50078DEBC /* WebCore.framework */; };
 		37BEC4E119491486008B4286 /* CompletionHandlerCallChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 37BEC4DF19491486008B4286 /* CompletionHandlerCallChecker.h */; };
@@ -3610,7 +3609,6 @@
 		37A64E5618F38F4600EB30F1 /* _WKFormInputSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKFormInputSession.h; sourceTree = "<group>"; };
 		37A709A61E3EA0FD00CA5969 /* WKDataDetectorTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDataDetectorTypes.h; sourceTree = "<group>"; };
 		37A709A81E3EA40C00CA5969 /* WKDataDetectorTypesInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDataDetectorTypesInternal.h; sourceTree = "<group>"; };
-		37B47E2C1D64DB76005F4EFF /* objcSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = objcSPI.h; sourceTree = "<group>"; };
 		37B5045119EEF31300CE2CF8 /* WKErrorPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKErrorPrivate.h; sourceTree = "<group>"; };
 		37BEC4DE19491486008B4286 /* CompletionHandlerCallChecker.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CompletionHandlerCallChecker.mm; sourceTree = "<group>"; };
 		37BEC4DF19491486008B4286 /* CompletionHandlerCallChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompletionHandlerCallChecker.h; sourceTree = "<group>"; };
@@ -7776,7 +7774,6 @@
 				574217912400E098002B303D /* LocalAuthenticationSPI.h */,
 				57B826402304EB3E00B72EB0 /* NearFieldSPI.h */,
 				3754D5441B3A29FD003A4C7F /* NSInvocationSPI.h */,
-				37B47E2C1D64DB76005F4EFF /* objcSPI.h */,
 				0E97D74C200E8FF300BF6643 /* SafeBrowsingSPI.h */,
 			);
 			path = Cocoa;
@@ -11946,7 +11943,6 @@
 				1C2184022233872800BAC700 /* NSAttributedStringPrivate.h in Headers */,
 				3754D5451B3A29FD003A4C7F /* NSInvocationSPI.h in Headers */,
 				BC8ACA1316670D89004C1941 /* ObjCObjectGraph.h in Headers */,
-				37B47E2D1D64DB76005F4EFF /* objcSPI.h in Headers */,
 				7CF47FFB17275C57008ACB91 /* PageBanner.h in Headers */,
 				BC6EDAA6111271C600E7678B /* PageClient.h in Headers */,
 				0FCB4E4618BBE044000FCFC9 /* PageClientImplIOS.h in Headers */,

Modified: trunk/Tools/ChangeLog (274763 => 274764)


--- trunk/Tools/ChangeLog	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Tools/ChangeLog	2021-03-22 18:45:13 UTC (rev 274764)
@@ -1,3 +1,14 @@
+2021-03-19  Darin Adler  <da...@apple.com>
+
+        [Cocoa] Make it possible to release a WKWebView on a non-main thread without a crash due to WKScriptMessage race
+        https://bugs.webkit.org/show_bug.cgi?id=222336
+
+        Reviewed by Chris Dumez.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
+        Use _close instead of WKWebView deallocation to trigger a call to stopURLSchemeTask,
+        since such delegate methods will intentionally no longer be delivered if triggered by deallocation.
+
 2021-03-22  Youenn Fablet  <you...@apple.com>
 
         Implement RTCDataChannel transfer out of process

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm (274763 => 274764)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2021-03-22 18:45:07 UTC (rev 274763)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2021-03-22 18:45:13 UTC (rev 274764)
@@ -558,7 +558,7 @@
         TestWebKitAPI::Util::run(&startedXHR);
         receivedMessage = false;
 
-        webView = nil;
+        [webView _close];
     }
     
     TestWebKitAPI::Util::run(&receivedStop);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to