Diff
Modified: trunk/Source/WTF/ChangeLog (282631 => 282632)
--- trunk/Source/WTF/ChangeLog 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Source/WTF/ChangeLog 2021-09-17 04:18:09 UTC (rev 282632)
@@ -1,3 +1,37 @@
+2021-09-16 David Kilzer <[email protected]>
+
+ WebKit::WebProcessPool should use a weak observer with CFNotificationCenter
+ <https://webkit.org/b/230227>
+ <rdar://problem/83067708>
+
+ Reviewed by Darin Adler.
+
+ Tests (API):
+ TestWTF.TypeCastsNS.checked_ns_cast
+ TestWTF.TypeCastsNS.dynamic_ns_cast
+ TestWTF.TypeCastsNS.dynamic_ns_cast_RetainPtr
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/PlatformMac.cmake:
+ - Add new header files to the project.
+
+ * wtf/cocoa/TypeCastsNS.h: Add.
+ (WTF::checked_ns_cast):
+ (WTF::dynamic_ns_cast):
+ - Add casts for NS objects similar to TypeCastsCF.h.
+
+ * wtf/PlatformHave.h:
+ (HAVE_NS_DIRECT_SUPPORT): Add.
+ - Note that clang for macOS 11 Big Sur claims to know about the
+ attributes, but will fail to compile if they are actually
+ used.
+
+ * wtf/spi/cocoa/NSObjCRuntimeSPI.h: Add.
+ (NS_DIRECT):
+ (NS_DIRECT_MEMBERS):
+ - Define compiler attributes for direct dispatch of Objective-C
+ methods.
+
2021-09-16 Philip Chimento <[email protected]>
Fixes for build-webkit --minimal
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (282631 => 282632)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2021-09-17 04:18:09 UTC (rev 282632)
@@ -389,7 +389,9 @@
413FE8F51F8D2EAB00F6D7D7 /* CallbackAggregator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackAggregator.h; sourceTree = "<group>"; };
430B47871AAAAC1A001223DA /* StringCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringCommon.h; sourceTree = "<group>"; };
4427C5A921F6D6C300A612A4 /* ASCIICType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASCIICType.cpp; sourceTree = "<group>"; };
+ 44309D4026EFC14A00402A67 /* NSObjCRuntimeSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSObjCRuntimeSPI.h; sourceTree = "<group>"; };
4468567225094FE8008CCA05 /* ThreadSanitizerSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadSanitizerSupport.h; sourceTree = "<group>"; };
+ 44CDE4D226EE6CDA009F6ACB /* TypeCastsNS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeCastsNS.h; sourceTree = "<group>"; };
46209A27266D543A007F8F4A /* CancellableTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CancellableTask.h; sourceTree = "<group>"; };
46BA9EAB1F4CD61E009A2BBC /* CompletionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompletionHandler.h; sourceTree = "<group>"; };
46BEB6E922FFDDD500269867 /* RefCounted.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RefCounted.cpp; sourceTree = "<group>"; };
@@ -1535,6 +1537,7 @@
CEA072A7236FFA160018839C /* CrashReporterClientSPI.h */,
E31BDE2822E913CC0029B105 /* MachVMSPI.h */,
1C503BE423AADEEA0072E66B /* NSLocaleSPI.h */,
+ 44309D4026EFC14A00402A67 /* NSObjCRuntimeSPI.h */,
93D191CF20CAECE800C51B8E /* objcSPI.h */,
2DA442FC24904CA000C9C59D /* OSLogSPI.h */,
A5098B011C16A4F900087797 /* SecuritySPI.h */,
@@ -1615,6 +1618,7 @@
A30D412C1F0DE0BA00B71954 /* SoftLinking.h */,
BC3FEB5E267FCD460054006A /* SpanCocoa.h */,
EB61EDC62409CCC0001EFE36 /* SystemTracingCocoa.cpp */,
+ 44CDE4D226EE6CDA009F6ACB /* TypeCastsNS.h */,
5CC0EE862162BC2200A1A842 /* URLCocoa.mm */,
93241657243BC2E50032FAAE /* VectorCocoa.h */,
E4A0AD3C1A96253C00536DF6 /* WorkQueueCocoa.cpp */,
Modified: trunk/Source/WTF/wtf/PlatformHave.h (282631 => 282632)
--- trunk/Source/WTF/wtf/PlatformHave.h 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Source/WTF/wtf/PlatformHave.h 2021-09-17 04:18:09 UTC (rev 282632)
@@ -846,6 +846,14 @@
#endif
#endif
+#if COMPILER(GCC_COMPATIBLE) && defined(__has_attribute)
+#if __has_attribute(objc_direct) && (!PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000)
+#if !defined(HAVE_NS_DIRECT_SUPPORT)
+#define HAVE_NS_DIRECT_SUPPORT 1
+#endif
+#endif
+#endif
+
#if PLATFORM(COCOA)
#if !defined(HAVE_CG_CONTEXT_DRAW_PATH_DIRECT)
#define HAVE_CG_CONTEXT_DRAW_PATH_DIRECT 1
Modified: trunk/Source/WTF/wtf/PlatformMac.cmake (282631 => 282632)
--- trunk/Source/WTF/wtf/PlatformMac.cmake 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Source/WTF/wtf/PlatformMac.cmake 2021-09-17 04:18:09 UTC (rev 282632)
@@ -20,6 +20,7 @@
cocoa/RuntimeApplicationChecksCocoa.h
cocoa/SoftLinking.h
cocoa/SpanCocoa.h
+ cocoa/TypeCastsNS.h
cocoa/VectorCocoa.h
darwin/WeakLinking.h
@@ -31,6 +32,7 @@
spi/cocoa/CrashReporterClientSPI.h
spi/cocoa/MachVMSPI.h
spi/cocoa/NSLocaleSPI.h
+ spi/cocoa/NSObjCRuntimeSPI.h
spi/cocoa/SecuritySPI.h
spi/cocoa/objcSPI.h
Added: trunk/Source/WTF/wtf/cocoa/TypeCastsNS.h (0 => 282632)
--- trunk/Source/WTF/wtf/cocoa/TypeCastsNS.h (rev 0)
+++ trunk/Source/WTF/wtf/cocoa/TypeCastsNS.h 2021-09-17 04:18:09 UTC (rev 282632)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014-2021 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.
+ */
+
+#pragma once
+
+#include <wtf/Assertions.h>
+#include <wtf/RetainPtr.h>
+
+namespace WTF {
+
+// Use checked_ns_cast<> instead of dynamic_ns_cast<> when a specific NS type is required.
+
+template<typename T> T* checked_ns_cast(id object)
+{
+ using ValueType = std::remove_pointer_t<T>;
+ using PtrType = ValueType*;
+
+ if (!object)
+ return nullptr;
+
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION([object isKindOfClass:[ValueType class]]);
+
+ return reinterpret_cast<PtrType>(object);
+}
+
+// Use dynamic_ns_cast<> instead of checked_ns_cast<> when actively checking NS types,
+// similar to dynamic_cast<> in C++. Be sure to include a nil check.
+
+template<typename T> T* dynamic_ns_cast(id object)
+{
+ using ValueType = std::remove_pointer_t<T>;
+ using PtrType = ValueType*;
+
+ if (![object isKindOfClass:[ValueType class]])
+ return nullptr;
+
+ return reinterpret_cast<PtrType>(object);
+}
+
+template<typename T, typename U> RetainPtr<T> dynamic_ns_cast(RetainPtr<U>&& object)
+{
+ if (![object isKindOfClass:[T class]])
+ return nullptr;
+
+ return WTFMove(object);
+}
+
+} // namespace WTF
+
+using WTF::checked_ns_cast;
+using WTF::dynamic_ns_cast;
Added: trunk/Source/WTF/wtf/spi/cocoa/NSObjCRuntimeSPI.h (0 => 282632)
--- trunk/Source/WTF/wtf/spi/cocoa/NSObjCRuntimeSPI.h (rev 0)
+++ trunk/Source/WTF/wtf/spi/cocoa/NSObjCRuntimeSPI.h 2021-09-17 04:18:09 UTC (rev 282632)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#include <Foundation/NSObjCRuntime_Private.h>
+
+#else
+
+#include <wtf/Platform.h>
+
+// Apply this to a specific method in the @interface or @implementation.
+#ifndef NS_DIRECT
+#if HAVE(NS_DIRECT_SUPPORT)
+#define NS_DIRECT __attribute__((objc_direct))
+#else
+#define NS_DIRECT
+#endif
+#endif
+
+// Apply this to the @interface or @implementation of a class.
+#ifndef NS_DIRECT_MEMBERS
+#if HAVE(NS_DIRECT_SUPPORT)
+#define NS_DIRECT_MEMBERS __attribute__((objc_direct_members))
+#else
+#define NS_DIRECT_MEMBERS
+#endif
+#endif
+
+#endif
Modified: trunk/Source/WebKit/ChangeLog (282631 => 282632)
--- trunk/Source/WebKit/ChangeLog 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Source/WebKit/ChangeLog 2021-09-17 04:18:09 UTC (rev 282632)
@@ -1,3 +1,66 @@
+2021-09-16 David Kilzer <[email protected]>
+
+ WebKit::WebProcessPool should use a weak observer with CFNotificationCenter
+ <https://webkit.org/b/230227>
+ <rdar://problem/83067708>
+
+ Reviewed by Darin Adler.
+
+ To fix the bug, implement an Objective-C class named
+ WKProcessPoolWeakObserver which contains an instance variable
+ holding a WeakPtr<WebProcessPool>, and tell CFNotificationCenter
+ to hold a weak reference to WKProcessPoolWeakObserver.
+
+ Since WKProcessPoolWeakObserver is self-contained within the
+ source file, it uses the NS_DIRECT_MEMBERS attribute since it
+ does not require the overhead of dynamic Objective-C method
+ dispatch.
+
+ * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+ (-[WKProcessPoolWeakObserver initWithWeakPtr:]): Add.
+ (-[WKProcessPoolWeakObserver pool]): Add.
+ - Implement WKProcessPoolWeakObserver class.
+ - Note that init methods can never be marked as NS_DIRECT, and
+ @property statements can't use NS_DIRECT in their declaration,
+ so the @property is declared in a category which uses
+ NS_DIRECT_MEMBERS.
+ (WebKit::extractWebProcessPool): Add.
+ - Static helper method for extracting RefPtr<WebProcessPool>
+ from type-punned WKProcessPoolWeakObserver.
+ (WebKit::WebProcessPool::backlightLevelDidChangeCallback):
+ (WebKit::WebProcessPool::accessibilityPreferencesChangedCallback):
+ (WebKit::WebProcessPool::mediaAccessibilityPreferencesChangedCallback):
+ (WebKit::WebProcessPool::colorPreferencesDidChangeCallback):
+ (WebKit::WebProcessPool::remoteWebInspectorEnabledCallback):
+ - Clean up function parameter list.
+ - Use extractWebProcessPool() helper method to get a
+ RefPtr<WebProcessPool> from `observer`.
+ (WebKit::WebProcessPool::addCFNotificationObserver): Add.
+ (WebKit::WebProcessPool::removeCFNotificationObserver): Add.
+ - Private helper methods to reduce duplicate code.
+ - Use m_weakObserver for CFNotificationCenter observer and
+ include _CFNotificationObserverIsObjC to fix the bug.
+ (WebKit::WebProcessPool::registerNotificationObservers):
+ - Make use of new addCFNotificationObserver() helper method.
+ - Fixes use of static_cast<CFStringRef> to make code ready for
+ ARC by using a __bridge cast or removing the static_cast when
+ CFSTR() is used.
+ (WebKit::WebProcessPool::unregisterNotificationObservers):
+ - Make use of new removeCFNotificationObserver() helper method.
+
+ * UIProcess/WebProcessPool.h:
+ - Add m_weakObserver instance variable to hold the
+ WKProcessPoolWeakObserver object.
+ (WebKit::WebProcessPool::addCFNotificationObserver): Add.
+ (WebKit::WebProcessPool::removeCFNotificationObserver): Add.
+ - Add declarations for new helper methods.
+ (WebKit::WebProcessPool::backlightLevelDidChangeCallback):
+ (WebKit::WebProcessPool::accessibilityPreferencesChangedCallback):
+ (WebKit::WebProcessPool::mediaAccessibilityPreferencesChangedCallback):
+ (WebKit::WebProcessPool::colorPreferencesDidChangeCallback):
+ (WebKit::WebProcessPool::remoteWebInspectorEnabledCallback):
+ - Clean up function parameter list.
+
2021-09-16 Cameron McCormack <[email protected]>
Support patterns with a wide gamut source painting into a display-p3 canvas
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (282631 => 282632)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2021-09-17 04:18:09 UTC (rev 282632)
@@ -65,6 +65,7 @@
#import <WebCore/VersionChecks.h>
#import <objc/runtime.h>
#import <pal/spi/cf/CFNetworkSPI.h>
+#import <pal/spi/cf/CFNotificationCenterSPI.h>
#import <sys/param.h>
#import <wtf/FileSystem.h>
#import <wtf/ProcessPrivilege.h>
@@ -71,6 +72,8 @@
#import <wtf/SoftLinking.h>
#import <wtf/cocoa/Entitlements.h>
#import <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
+#import <wtf/cocoa/TypeCastsNS.h>
+#import <wtf/spi/cocoa/NSObjCRuntimeSPI.h>
#import <wtf/spi/darwin/SandboxSPI.h>
#import <wtf/spi/darwin/dyldSPI.h>
#import <wtf/text/TextStream.h>
@@ -131,6 +134,35 @@
#define WEBPROCESSPOOL_RELEASE_LOG(channel, fmt, ...) RELEASE_LOG(channel, "%p - WebProcessPool::" fmt, this, ##__VA_ARGS__)
+@interface WKProcessPoolWeakObserver : NSObject {
+ WeakPtr<WebKit::WebProcessPool> m_weakPtr;
+}
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithWeakPtr:(WeakPtr<WebKit::WebProcessPool>&&)weakPtr NS_DESIGNATED_INITIALIZER;
+@end
+
+NS_DIRECT_MEMBERS
+@interface WKProcessPoolWeakObserver (Direct)
+@property (nonatomic, readonly) RefPtr<WebKit::WebProcessPool> pool;
+@end
+
+@implementation WKProcessPoolWeakObserver
+- (instancetype)initWithWeakPtr:(WeakPtr<WebKit::WebProcessPool>&&)weakPtr
+{
+ if ((self = [super init]))
+ m_weakPtr = WTFMove(weakPtr);
+ return self;
+}
+@end
+
+NS_DIRECT_MEMBERS
+@implementation WKProcessPoolWeakObserver (Direct)
+- (RefPtr<WebKit::WebProcessPool>)pool
+{
+ return makeRefPtr(m_weakPtr.get());
+}
+@end
+
namespace WebKit {
using namespace WebCore;
@@ -603,29 +635,43 @@
return !m_userObservablePageCounter.value() && !m_processSuppressionDisabledForPageCounter.value();
}
+static inline RefPtr<WebProcessPool> extractWebProcessPool(void* observer)
+{
+ RetainPtr strongObserver { dynamic_ns_cast<WKProcessPoolWeakObserver>(reinterpret_cast<id>(observer)) };
+ if (!strongObserver)
+ return nullptr;
+ return [strongObserver pool];
+}
+
#if PLATFORM(IOS_FAMILY) && !PLATFORM(MACCATALYST)
float WebProcessPool::displayBrightness()
{
return BKSDisplayBrightnessGetCurrent();
}
-
-void WebProcessPool::backlightLevelDidChangeCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
+
+void WebProcessPool::backlightLevelDidChangeCallback(CFNotificationCenterRef, void* observer, CFStringRef, const void*, CFDictionaryRef)
{
- auto* pool = reinterpret_cast<WebProcessPool*>(observer);
+ auto pool = extractWebProcessPool(observer);
+ if (!pool)
+ return;
pool->sendToAllProcesses(Messages::WebProcess::BacklightLevelDidChange(BKSDisplayBrightnessGetCurrent()));
}
#endif
-void WebProcessPool::accessibilityPreferencesChangedCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo)
+void WebProcessPool::accessibilityPreferencesChangedCallback(CFNotificationCenterRef, void* observer, CFStringRef, const void*, CFDictionaryRef)
{
- auto* pool = reinterpret_cast<WebProcessPool*>(observer);
+ auto pool = extractWebProcessPool(observer);
+ if (!pool)
+ return;
pool->sendToAllProcesses(Messages::WebProcess::AccessibilityPreferencesDidChange(accessibilityPreferences()));
}
#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
-void WebProcessPool::mediaAccessibilityPreferencesChangedCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo)
+void WebProcessPool::mediaAccessibilityPreferencesChangedCallback(CFNotificationCenterRef, void* observer, CFStringRef, const void*, CFDictionaryRef)
{
- auto* pool = reinterpret_cast<WebProcessPool*>(observer);
+ auto pool = extractWebProcessPool(observer);
+ if (!pool)
+ return;
auto captionDisplayMode = WebCore::CaptionUserPreferencesMediaAF::platformCaptionDisplayMode();
auto preferredLanguages = WebCore::CaptionUserPreferencesMediaAF::platformPreferredLanguages();
pool->sendToAllProcesses(Messages::WebProcess::SetMediaAccessibilityPreferences(captionDisplayMode, preferredLanguages));
@@ -633,17 +679,21 @@
#endif
#if PLATFORM(MAC)
-void WebProcessPool::colorPreferencesDidChangeCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
+void WebProcessPool::colorPreferencesDidChangeCallback(CFNotificationCenterRef, void* observer, CFStringRef, const void*, CFDictionaryRef)
{
- auto* pool = reinterpret_cast<WebProcessPool*>(observer);
+ auto pool = extractWebProcessPool(observer);
+ if (!pool)
+ return;
pool->sendToAllProcesses(Messages::WebProcess::ColorPreferencesDidChange());
}
#endif
#if ENABLE(REMOTE_INSPECTOR) && PLATFORM(IOS_FAMILY) && !PLATFORM(MACCATALYST)
-void WebProcessPool::remoteWebInspectorEnabledCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo)
+void WebProcessPool::remoteWebInspectorEnabledCallback(CFNotificationCenterRef, void* observer, CFStringRef, const void*, CFDictionaryRef)
{
- auto* pool = reinterpret_cast<WebProcessPool*>(observer);
+ auto pool = extractWebProcessPool(observer);
+ if (!pool)
+ return;
for (auto& process : pool->m_processes)
process->enableRemoteInspectorIfNeeded();
}
@@ -662,6 +712,17 @@
}
#endif
+void WebProcessPool::addCFNotificationObserver(CFNotificationCallback callback, CFStringRef name, CFNotificationCenterRef center)
+{
+ auto coalesceBehavior = static_cast<CFNotificationSuspensionBehavior>(CFNotificationSuspensionBehaviorCoalesce | _CFNotificationObserverIsObjC);
+ CFNotificationCenterAddObserver(center, (__bridge const void*)m_weakObserver.get(), callback, name, nullptr, coalesceBehavior);
+}
+
+void WebProcessPool::removeCFNotificationObserver(CFStringRef name, CFNotificationCenterRef center)
+{
+ CFNotificationCenterRemoveObserver(center, (__bridge const void*)m_weakObserver.get(), name, nullptr);
+}
+
void WebProcessPool::registerNotificationObservers()
{
#if !PLATFORM(IOS_FAMILY)
@@ -721,12 +782,14 @@
setApplicationIsActive(false);
}];
- CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), this, colorPreferencesDidChangeCallback, AppleColorPreferencesChangedNotification, nullptr, CFNotificationSuspensionBehaviorCoalesce);
+ m_weakObserver = adoptNS([[WKProcessPoolWeakObserver alloc] initWithWeakPtr:makeWeakPtr(*this)]);
+
+ addCFNotificationObserver(colorPreferencesDidChangeCallback, AppleColorPreferencesChangedNotification, CFNotificationCenterGetDistributedCenter());
#elif !PLATFORM(MACCATALYST)
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, backlightLevelDidChangeCallback, static_cast<CFStringRef>(UIBacklightLevelChangedNotification), nullptr, CFNotificationSuspensionBehaviorCoalesce);
+ addCFNotificationObserver(backlightLevelDidChangeCallback, (__bridge CFStringRef)UIBacklightLevelChangedNotification);
#if PLATFORM(IOS)
#if ENABLE(REMOTE_INSPECTOR)
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, remoteWebInspectorEnabledCallback, static_cast<CFStringRef>(CFSTR(WIRServiceEnabledNotification)), nullptr, CFNotificationSuspensionBehaviorCoalesce);
+ addCFNotificationObserver(remoteWebInspectorEnabledCallback, CFSTR(WIRServiceEnabledNotification));
#endif
#endif // PLATFORM(IOS)
#endif // !PLATFORM(IOS_FAMILY)
@@ -762,14 +825,14 @@
});
#if HAVE(PER_APP_ACCESSIBILITY_PREFERENCES)
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, accessibilityPreferencesChangedCallback, kAXSReduceMotionChangedNotification, nullptr, CFNotificationSuspensionBehaviorCoalesce);
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, accessibilityPreferencesChangedCallback, kAXSIncreaseButtonLegibilityNotification, nullptr, CFNotificationSuspensionBehaviorCoalesce);
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, accessibilityPreferencesChangedCallback, kAXSEnhanceTextLegibilityChangedNotification, nullptr, CFNotificationSuspensionBehaviorCoalesce);
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, accessibilityPreferencesChangedCallback, kAXSDarkenSystemColorsEnabledNotification, nullptr, CFNotificationSuspensionBehaviorCoalesce);
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, accessibilityPreferencesChangedCallback, kAXSInvertColorsEnabledNotification, nullptr, CFNotificationSuspensionBehaviorCoalesce);
+ addCFNotificationObserver(accessibilityPreferencesChangedCallback, kAXSReduceMotionChangedNotification);
+ addCFNotificationObserver(accessibilityPreferencesChangedCallback, kAXSIncreaseButtonLegibilityNotification);
+ addCFNotificationObserver(accessibilityPreferencesChangedCallback, kAXSEnhanceTextLegibilityChangedNotification);
+ addCFNotificationObserver(accessibilityPreferencesChangedCallback, kAXSDarkenSystemColorsEnabledNotification);
+ addCFNotificationObserver(accessibilityPreferencesChangedCallback, kAXSInvertColorsEnabledNotification);
#endif
#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, mediaAccessibilityPreferencesChangedCallback, kMAXCaptionAppearanceSettingsChangedNotification, nullptr, CFNotificationSuspensionBehaviorCoalesce);
+ addCFNotificationObserver(mediaAccessibilityPreferencesChangedCallback, kMAXCaptionAppearanceSettingsChangedNotification);
#endif
}
@@ -786,12 +849,12 @@
[[NSWorkspace.sharedWorkspace notificationCenter] removeObserver:m_accessibilityDisplayOptionsNotificationObserver.get()];
[[NSNotificationCenter defaultCenter] removeObserver:m_scrollerStyleNotificationObserver.get()];
[[NSNotificationCenter defaultCenter] removeObserver:m_deactivationObserver.get()];
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), this, AppleColorPreferencesChangedNotification, nullptr);
+ removeCFNotificationObserver(AppleColorPreferencesChangedNotification, CFNotificationCenterGetDistributedCenter());
#elif !PLATFORM(MACCATALYST)
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, static_cast<CFStringRef>(UIBacklightLevelChangedNotification) , nullptr);
+ removeCFNotificationObserver((__bridge CFStringRef)UIBacklightLevelChangedNotification);
#if PLATFORM(IOS)
#if ENABLE(REMOTE_INSPECTOR)
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, CFSTR(WIRServiceEnabledNotification), nullptr);
+ removeCFNotificationObserver(CFSTR(WIRServiceEnabledNotification));
#endif
#endif // PLATFORM(IOS)
#endif // !PLATFORM(IOS_FAMILY)
@@ -806,15 +869,17 @@
m_powerSourceNotifier = nullptr;
#if HAVE(PER_APP_ACCESSIBILITY_PREFERENCES)
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, kAXSReduceMotionChangedNotification, nullptr);
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, kAXSIncreaseButtonLegibilityNotification, nullptr);
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, kAXSEnhanceTextLegibilityChangedNotification, nullptr);
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, kAXSDarkenSystemColorsEnabledNotification, nullptr);
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, kAXSInvertColorsEnabledNotification, nullptr);
+ removeCFNotificationObserver(kAXSReduceMotionChangedNotification);
+ removeCFNotificationObserver(kAXSIncreaseButtonLegibilityNotification);
+ removeCFNotificationObserver(kAXSEnhanceTextLegibilityChangedNotification);
+ removeCFNotificationObserver(kAXSDarkenSystemColorsEnabledNotification);
+ removeCFNotificationObserver(kAXSInvertColorsEnabledNotification);
#endif
#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, kMAXCaptionAppearanceSettingsChangedNotification, nullptr);
+ removeCFNotificationObserver(kMAXCaptionAppearanceSettingsChangedNotification);
#endif
+
+ m_weakObserver = nil;
}
bool WebProcessPool::isURLKnownHSTSHost(const String& urlString) const
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (282631 => 282632)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-09-17 04:18:09 UTC (rev 282632)
@@ -64,6 +64,7 @@
OBJC_CLASS NSSet;
OBJC_CLASS NSString;
OBJC_CLASS WKPreferenceObserver;
+OBJC_CLASS WKProcessPoolWeakObserver;
#if PLATFORM(MAC)
OBJC_CLASS WKWebInspectorPreferenceObserver;
#endif
@@ -549,6 +550,9 @@
bool usesSingleWebProcess() const { return m_configuration->usesSingleWebProcess(); }
#if PLATFORM(COCOA)
+ void addCFNotificationObserver(CFNotificationCallback, CFStringRef name, CFNotificationCenterRef = CFNotificationCenterGetDarwinNotifyCenter());
+ void removeCFNotificationObserver(CFStringRef name, CFNotificationCenterRef = CFNotificationCenterGetDarwinNotifyCenter());
+
void registerNotificationObservers();
void unregisterNotificationObservers();
#endif
@@ -567,22 +571,22 @@
#if PLATFORM(IOS_FAMILY) && !PLATFORM(MACCATALYST)
static float displayBrightness();
- static void backlightLevelDidChangeCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo);
+ static void backlightLevelDidChangeCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void* postingObject, CFDictionaryRef userInfo);
#if ENABLE(REMOTE_INSPECTOR)
- static void remoteWebInspectorEnabledCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo);
+ static void remoteWebInspectorEnabledCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void* postingObject, CFDictionaryRef userInfo);
#endif
#endif
#if PLATFORM(COCOA)
- static void accessibilityPreferencesChangedCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo);
+ static void accessibilityPreferencesChangedCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void* postingObject, CFDictionaryRef userInfo);
#endif
#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- static void mediaAccessibilityPreferencesChangedCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo);
+ static void mediaAccessibilityPreferencesChangedCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void* postingObject, CFDictionaryRef userInfo);
#endif
#if PLATFORM(MAC)
- static void colorPreferencesDidChangeCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo);
+ static void colorPreferencesDidChangeCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void* postingObject, CFDictionaryRef userInfo);
#endif
#if ENABLE(CFPREFS_DIRECT_MODE)
@@ -689,6 +693,8 @@
RetainPtr<NSObject> m_activationObserver;
RetainPtr<NSObject> m_accessibilityEnabledObserver;
RetainPtr<NSObject> m_applicationLaunchObserver;
+
+ RetainPtr<WKProcessPoolWeakObserver> m_weakObserver;
#endif
bool m_processTerminationEnabled { true };
Modified: trunk/Tools/ChangeLog (282631 => 282632)
--- trunk/Tools/ChangeLog 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Tools/ChangeLog 2021-09-17 04:18:09 UTC (rev 282632)
@@ -1,3 +1,16 @@
+2021-09-16 David Kilzer <[email protected]>
+
+ WebKit::WebProcessPool should use a weak observer with CFNotificationCenter
+ <https://webkit.org/b/230227>
+ <rdar://problem/83067708>
+
+ Reviewed by Darin Adler.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ - Add TypeCastsNS.mm to the project.
+ * TestWebKitAPI/Tests/WTF/cocoa/TypeCastsNS.mm: Add.
+ (TestWebKitAPI::TEST): Add tests for <wtf/TypeCastsNS.h>.
+
2021-09-16 Philip Chimento <[email protected]>
Fixes for build-webkit --minimal
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (282631 => 282632)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-09-17 03:12:11 UTC (rev 282631)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-09-17 04:18:09 UTC (rev 282632)
@@ -267,6 +267,7 @@
448D7E471EA6C55500ECC756 /* EnvironmentUtilitiesTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 448D7E451EA6C55500ECC756 /* EnvironmentUtilitiesTest.cpp */; };
44AC8BC621D0245A00CAFB34 /* RetainPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC029B161486AD6400817DA9 /* RetainPtr.cpp */; };
44C2FBE225E7592C00ABC72F /* WKAppHighlights.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44C2FBE125E7592C00ABC72F /* WKAppHighlights.mm */; };
+ 44CDE4D426EE6E4A009F6ACB /* TypeCastsNS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44CDE4D326EE6E41009F6ACB /* TypeCastsNS.mm */; };
44CF31FD249941E8009CB6CB /* ContextMenuAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 44CF31FB24993F66009CB6CB /* ContextMenuAction.cpp */; };
4612C2B9210A6ACE00B788A6 /* LoadFileThenReload.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4612C2B8210A6ABF00B788A6 /* LoadFileThenReload.mm */; };
4628C8E92367ABD100B073F0 /* WKSecurityOrigin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4628C8E82367ABBC00B073F0 /* WKSecurityOrigin.cpp */; };
@@ -2099,6 +2100,7 @@
448D7E451EA6C55500ECC756 /* EnvironmentUtilitiesTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EnvironmentUtilitiesTest.cpp; sourceTree = "<group>"; };
44A622C114A0E2B60048515B /* WTFStringUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFStringUtilities.h; sourceTree = "<group>"; };
44C2FBE125E7592C00ABC72F /* WKAppHighlights.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKAppHighlights.mm; sourceTree = "<group>"; };
+ 44CDE4D326EE6E41009F6ACB /* TypeCastsNS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TypeCastsNS.mm; sourceTree = "<group>"; };
44CF31FB24993F66009CB6CB /* ContextMenuAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContextMenuAction.cpp; sourceTree = "<group>"; };
4612C2B8210A6ABF00B788A6 /* LoadFileThenReload.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadFileThenReload.mm; sourceTree = "<group>"; };
4628C8E82367ABBC00B073F0 /* WKSecurityOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKSecurityOrigin.cpp; sourceTree = "<group>"; };
@@ -4983,6 +4985,7 @@
BC3FEB63267FCF740054006A /* SpanCocoa.mm */,
1C4616A626BB172F00F8C9F6 /* TextStreamCocoa.cpp */,
1C46169E26BA510700F8C9F6 /* TextStreamCocoa.mm */,
+ 44CDE4D326EE6E41009F6ACB /* TypeCastsNS.mm */,
E3C21A7B21B25CA2003B31A3 /* URLExtras.mm */,
);
path = cocoa;
@@ -5356,6 +5359,7 @@
E38A0D351FD50CC300E98C8B /* Threading.cpp in Sources */,
5311BD5E1EA9490E00525281 /* ThreadMessages.cpp in Sources */,
0F2C20B81DCD545000542D9E /* Time.cpp in Sources */,
+ 44CDE4D426EE6E4A009F6ACB /* TypeCastsNS.mm in Sources */,
E324A6F02041C82000A76593 /* UniqueArray.cpp in Sources */,
E3A1E78221B25B7A008C6007 /* URL.cpp in Sources */,
E3C21A7C21B25CA2003B31A3 /* URLExtras.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/cocoa/TypeCastsNS.mm (0 => 282632)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/cocoa/TypeCastsNS.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/cocoa/TypeCastsNS.mm 2021-09-17 04:18:09 UTC (rev 282632)
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#import "config.h"
+#import <wtf/cocoa/TypeCastsNS.h>
+
+#import <wtf/StdLibExtras.h>
+
+@interface MyObjectSubtype : NSObject
+@end
+
+@implementation MyObjectSubtype
+@end
+
+namespace TestWebKitAPI {
+
+using namespace WTF;
+
+TEST(TypeCastsNS, checked_ns_cast)
+{
+ EXPECT_EQ(nil, checked_ns_cast<NSString>(nil));
+
+ {
+ auto object = adoptNS(reinterpret_cast<id>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ EXPECT_EQ(object.get(), checked_ns_cast<NSString>(object.get()));
+ EXPECT_EQ(object.get(), checked_ns_cast<NSObject>(object.get()));
+ }
+
+ {
+ auto object = adoptNS(reinterpret_cast<NSObject *>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ EXPECT_EQ(object.get(), checked_ns_cast<NSString>(object.get()));
+ }
+
+ {
+ auto object = adoptNS([[NSString alloc] initWithFormat:@"%s", "Hello world"]);
+ EXPECT_EQ(object.get(), checked_ns_cast<NSObject>(object.get()));
+ }
+}
+
+TEST(TypeCastsNS, dynamic_ns_cast)
+{
+ EXPECT_EQ(nil, dynamic_ns_cast<NSString>(nil));
+
+ {
+ auto object = adoptNS(reinterpret_cast<id>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ EXPECT_EQ(object.get(), dynamic_ns_cast<NSString>(object.get()));
+ EXPECT_EQ(object.get(), dynamic_ns_cast<NSObject>(object.get()));
+ EXPECT_EQ(nil, dynamic_ns_cast<NSArray>(object.get()));
+ }
+
+ {
+ auto object = adoptNS(reinterpret_cast<NSObject *>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ EXPECT_EQ(object.get(), dynamic_ns_cast<NSString>(object.get()));
+ EXPECT_EQ(nil, dynamic_ns_cast<NSArray>(object.get()));
+ }
+
+ {
+ auto object = adoptNS([[NSString alloc] initWithFormat:@"%s", "Hello world"]);
+ EXPECT_EQ(object.get(), dynamic_ns_cast<NSObject>(object.get()));
+ EXPECT_EQ(nil, dynamic_ns_cast<NSArray>(object.get()));
+ }
+
+ {
+ auto object = adoptNS(reinterpret_cast<id>([[NSObject alloc] init]));
+ EXPECT_EQ(object.get(), dynamic_ns_cast<NSObject>(object.get()));
+ EXPECT_EQ(nil, dynamic_ns_cast<MyObjectSubtype>(object.get()));
+ }
+
+ {
+ auto object = adoptNS([[NSObject alloc] init]);
+ EXPECT_EQ(nil, dynamic_ns_cast<MyObjectSubtype>(object.get()));
+ }
+}
+
+TEST(TypeCastsNS, dynamic_ns_cast_RetainPtr)
+{
+ {
+ RetainPtr<NSString> object;
+ auto objectCast = dynamic_ns_cast<NSString>(WTFMove(object));
+ EXPECT_EQ(nil, object.get());
+ EXPECT_EQ(nil, objectCast.get());
+ }
+
+ {
+ auto object = adoptNS(reinterpret_cast<id>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ id objectPtr = object.get();
+ auto objectCast = dynamic_ns_cast<NSString>(WTFMove(object));
+ EXPECT_EQ(nil, object.get());
+ EXPECT_EQ(objectPtr, objectCast.get());
+ objectPtr = nil; // For ARC.
+ EXPECT_EQ(1U, [objectCast retainCount]);
+
+ object = adoptNS(reinterpret_cast<id>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ objectPtr = object.get();
+ auto objectCast2 = dynamic_ns_cast<NSObject>(WTFMove(object));
+ EXPECT_EQ(nil, object.get());
+ EXPECT_EQ(objectPtr, objectCast2.get());
+ objectPtr = nil; // For ARC.
+ EXPECT_EQ(1U, [objectCast2 retainCount]);
+
+ object = adoptNS(reinterpret_cast<id>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ objectPtr = object.get();
+ auto objectCast3 = dynamic_ns_cast<NSArray>(WTFMove(object));
+ EXPECT_EQ(objectPtr, object.get());
+ EXPECT_EQ(nil, objectCast3.get());
+ objectPtr = nil; // For ARC.
+ EXPECT_EQ(1U, [object retainCount]);
+ }
+
+ {
+ auto object = adoptNS(reinterpret_cast<NSObject *>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ id objectPtr = object.get();
+ auto objectCast = dynamic_ns_cast<NSString>(WTFMove(object));
+ EXPECT_EQ(nil, object.get());
+ EXPECT_EQ(objectPtr, objectCast.get());
+ objectPtr = nil;
+ EXPECT_EQ(1U, [objectCast retainCount]);
+
+ object = adoptNS(reinterpret_cast<NSObject *>([[NSString alloc] initWithFormat:@"%s", "Hello world"]));
+ objectPtr = object.get();
+ auto objectCast2 = dynamic_ns_cast<NSArray>(WTFMove(object));
+ EXPECT_EQ(objectPtr, object.get());
+ EXPECT_EQ(nil, objectCast2.get());
+ objectPtr = nil;
+ EXPECT_EQ(1U, [object retainCount]);
+ }
+
+ {
+ auto object = adoptNS([[NSString alloc] initWithFormat:@"%s", "Hello world"]);
+ id objectPtr = object.get();
+ auto objectCast = dynamic_ns_cast<NSObject>(WTFMove(object));
+ EXPECT_EQ(nil, object.get());
+ EXPECT_EQ(objectPtr, objectCast.get());
+ objectPtr = nil;
+ EXPECT_EQ(1U, [objectCast retainCount]);
+
+ object = adoptNS([[NSString alloc] initWithFormat:@"%s", "Hello world"]);
+ objectPtr = object.get();
+ auto objectCast2 = dynamic_ns_cast<NSArray>(WTFMove(object));
+ EXPECT_EQ(objectPtr, object.get());
+ EXPECT_EQ(nil, objectCast2.get());
+ objectPtr = nil;
+ EXPECT_EQ(1U, [object retainCount]);
+ }
+
+ {
+ auto object = adoptNS(reinterpret_cast<id>([[NSObject alloc] init]));
+ id objectPtr = object.get();
+ auto objectCast = dynamic_ns_cast<NSObject>(WTFMove(object));
+ EXPECT_EQ(nil, object.get());
+ EXPECT_EQ(objectPtr, objectCast.get());
+ objectPtr = nil; // For ARC.
+ EXPECT_EQ(1U, [objectCast retainCount]);
+
+ object = adoptNS(reinterpret_cast<id>([[NSObject alloc] init]));
+ objectPtr = object.get();
+ auto objectCast2 = dynamic_ns_cast<MyObjectSubtype>(WTFMove(object));
+ EXPECT_EQ(objectPtr, object.get());
+ EXPECT_EQ(nil, objectCast2.get());
+ objectPtr = nil; // For ARC.
+ EXPECT_EQ(1U, [object retainCount]);
+ }
+
+ {
+ auto object = adoptNS([[NSObject alloc] init]);
+ id objectPtr = object.get();
+ auto objectCast = dynamic_ns_cast<MyObjectSubtype>(WTFMove(object));
+ EXPECT_EQ(objectPtr, object.get());
+ EXPECT_EQ(nil, objectCast.get());
+ objectPtr = nil; // For ARC.
+ EXPECT_EQ(1U, [object retainCount]);
+ }
+}
+
+} // namespace TestWebKitAPI