Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: cbf0ef68ade64b72082fcc6de3b06f70db1fa46f
      
https://github.com/WebKit/WebKit/commit/cbf0ef68ade64b72082fcc6de3b06f70db1fa46f
  Author: Richard Robinson <[email protected]>
  Date:   2026-08-26 (Wed, 26 Aug 2026)

  Changed paths:
    M Source/WTF/wtf/CompletionHandler.h
    M Source/WTF/wtf/OptionSet.h
    M Source/WTF/wtf/module.modulemap
    M Source/WebKit/CMakeLists.txt
    A Source/WebKit/Shared/WTFCompletionHandler+Extras.swift
    M Source/WebKit/UIProcess/WebPageProxy.swift
    M Source/WebKit/UIProcess/mac/WKTextSelectionController.swift
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj
    M Tools/TestWebKitAPI/Configurations/TestWTFLibrary.xcconfig
    A Tools/TestWebKitAPI/Helpers/WTFCompletionHandler+Extras.swift
    M Tools/TestWebKitAPI/Helpers/cocoa/HTTPServer.swift
    M Tools/TestWebKitAPI/TestBundle/TestWebKitAPIBundle-Bridging-Header.h
    A Tools/TestWebKitAPI/TestWTFLibrary/SwiftCxxInteropTestbed.cpp
    A Tools/TestWebKitAPI/TestWTFLibrary/SwiftCxxInteropTestbed.h
    A Tools/TestWebKitAPI/TestWTFLibrary/TestWTFLibrary.swift
    A Tools/TestWebKitAPI/TestWTFLibrary/module.modulemap
    M Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
    R Tools/TestWebKitAPI/Tests/WTF/cocoa/SwiftCxxInteropTestbed.cpp
    R Tools/TestWebKitAPI/Tests/WTF/cocoa/SwiftCxxInteropTestbed.h
    M Tools/TestWebKitAPI/Tests/WTF/cocoa/SwiftCxxInteropTests.swift
    M Tools/TestWebKitAPI/Tests/WebKit/WebPage/JSHandleTests.swift
    M Tools/TestWebKitAPI/Tests/WebKit/WebPage/WebPageTests.swift

  Log Message:
  -----------
  [Swift in WebKit] Introduce a bridging mechanism to create 
`WTF::CompletionHandler`s in Swift
https://bugs.webkit.org/show_bug.cgi?id=322377
rdar://185660724

Reviewed by Adrian Taylor.

Create an abstraction to allow `WTF::CompletionHandler` types to be properly 
constructed in Swift.
This is done by designing a pair of Swift protocols which 
`WTF::CompletionHandler` specializations
may conform to: `CxxCompletionHandler` for specializations taking a single 
argument, and
`CxxVoidCompletionHandler` for those taking none. Both refine 
`CxxCompletionHandlerBase`, which
provides the initializers.

Previously, Swift created these by relying on `WTF::CompletionHandler`'s 
Objective-C block
constructor, which was only exposed under `#ifdef __swift__`. That is now 
deleted unconditionally,
because implicitly bridging a Swift closure to a block gave no control over the 
closure's lifetime
and forced every callsite to spell out a `WTF::ThreadLikeAssertion` by hand. It 
was also not cross-platform.
Instead, a Swift closure is now reduced to the C ABI it fundamentally is (a 
function pointer, an opaque
context, and a destructor for that context) and `WTF::CompletionHandler` gains 
a constructor accepting
exactly that. The context is owned by a `std::unique_ptr<void, 
SwiftClosureDestroy>` captured by the
resulting handler, so it is destroyed together with the handler.

On the Swift side, the closure is stored in a class box passed across as a 
retained opaque pointer.
The box is deliberately split into a generic `SwiftClosureBox<Argument>` and a 
non-generic
`ErasedSwiftClosureBox` base, since a C function pointer cannot be formed from 
a closure that
captures generic parameters.

Note that because WTF does not yet support Swift, 
`WTFCompletionHandler+Extras.swift` must have a
copy in TestWTFLibrary for now.

The `callAsFunction` protocol requirement is witnessed by the imported C++ 
`operator()`. This is what
makes the compiler check that the `Argument` associated type matches the 
parameter type C++ actually
passes, so a mismatched conformance fails to compile rather than silently 
reinterpreting memory.

This abstraction currently does not support completion handlers whose 
parameters are noncopyable
types; this will be done in a subsequent change.

It also only supports completion handlers whose parameter list is of arity-0 or 
arity-1, and whose
return type is void; supporting arbitrary arity-n parameter lists is not 
currently prioritized due
to its infrequent use. Both restrictions are enforced at compile time by 
`static_assert`.

Tests: Tools/TestWebKitAPI/Tests/WTF/cocoa/SwiftCxxInteropTests.swift
       Tools/TestWebKitAPI/Tests/WebKit/WebPage/JSHandleTests.swift
       Tools/TestWebKitAPI/Tests/WebKit/WebPage/WebPageTests.swift

* Source/WTF/wtf/CompletionHandler.h:
(WTF::CompletionHandler<Out):
(WTF::adopt):
(WTF::CompletionHandlerWithFinalizer<Out):
(WTF::Detail::CallableWrapper<CompletionHandler<Out):

Add the `SwiftClosureInvoke` and `SwiftClosureDestroy` aliases describing the C 
ABI a Swift closure
reduces to, along with the constructor accepting them. Add an `Argument` alias 
for the Swift
protocols to key off of, and `VoidCompletionHandler` / `BoolCompletionHandler` 
aliases for the two
specializations common enough to conform out of the box.

Annotate the pointers in this header for nullability, which is required now 
that the Swift closure
typedefs introduce nullability into it.

* Source/WTF/wtf/OptionSet.h:

Use a different spelling for the friendship to ConstexprOptionSet to workaround 
a compiler bug (rdar://185869726).

* Source/WTF/wtf/module.modulemap:
* Source/WebKit/CMakeLists.txt:
* Source/WebKit/Shared/WTFCompletionHandler+Extras.swift: Added.
(CxxCompletionHandlerBase.init(_:)):
(ErasedSwiftClosureBox.call(with:)):
(SwiftClosureBox.init(_:)):
(SwiftClosureBox.call(with:)):
(CxxCompletionHandler.callAsFunction(_:)):
(CxxVoidCompletionHandler.callAsFunction):
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:

* Source/WebKit/UIProcess/WebPageProxy.swift:
(WebKit.WebPageProxy.selectWithGesture(at:type:state:isInteractingWithFocusedElement:)):
 Deleted.
(WebKit.WebPageProxy.selectPosition(at:isInteractingWithFocusedElement:)): 
Deleted.
(WebKit.WebPageProxy.selectText(at:by:isInteractingWithFocusedElement:)): 
Deleted.
(WebKit.WebPageProxy.updateSelection(withExtentPoint:by:isInteractingWithFocusedElement:source:)):
 Deleted.
(WebKit.selectPosition(at:isInteractingWithFocusedElement:)): Deleted.
* Source/WebKit/UIProcess/mac/WKTextSelectionController.swift:
(WKTextSelectionController.reextendSelectionForAutoscrollIfNeeded):
(WKTextSelectionController.moveInsertionCursor(to:placeAtWordBoundary:)):
(WKTextSelectionController.beginRangeSelection(at:with:)):
(WKTextSelectionController.continueRangeSelection(at:)):

Simplify the existing call-sites. These hand-written `async` wrappers existed 
only to hide the
boilerplate the block constructor demanded; with the continuation initializer, 
the callers can now
wrap the C++ functions directly and the wrappers earn their keep no longer.

* Tools/TestWebKitAPI/Configurations/TestWTFLibrary.xcconfig:
* Tools/TestWebKitAPI/Helpers/WTFCompletionHandler+Extras.swift: Added.
(CxxCompletionHandlerBase.init(_:)):
(ErasedSwiftClosureBox.call(with:)):
(SwiftClosureBox.init(_:)):
(SwiftClosureBox.call(with:)):
(CxxCompletionHandler.callAsFunction(_:)):
(CxxVoidCompletionHandler.callAsFunction):
* Tools/TestWebKitAPI/TestBundle/TestWebKitAPIBundle-Bridging-Header.h:
* Tools/TestWebKitAPI/TestWTFLibrary/TestWTFLibrary.swift: Added.
* Tools/TestWebKitAPI/TestWTFLibrary/module.modulemap: Added.
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Helpers/cocoa/HTTPServer.swift:
(HTTPServer.run(_:)):
* Tools/TestWebKitAPI/TestWTFLibrary/SwiftCxxInteropTestbed.h: Renamed from 
Tools/TestWebKitAPI/Tests/WTF/cocoa/SwiftCxxInteropTestbed.h.
* Tools/TestWebKitAPI/TestWTFLibrary/SwiftCxxInteropTestbed.cpp: Renamed from 
Tools/TestWebKitAPI/Tests/WTF/cocoa/SwiftCxxInteropTestbed.cpp.
(SwiftCxxInteropTestbed::callIntBoolFunction):
(SwiftCxxInteropTestbed::callIntCompletionHandler):
(SwiftCxxInteropTestbed::callVoidCompletionHandler):
(SwiftCxxInteropTestbed::storedIntCompletionHandler):
(SwiftCxxInteropTestbed::storeIntCompletionHandler):
(SwiftCxxInteropTestbed::invokeStoredIntCompletionHandler):
(SwiftCxxInteropTestbed::resetStoredIntCompletionHandler):
* Tools/TestWebKitAPI/Tests/WTF/cocoa/SwiftCxxInteropTests.swift:
(Recorder.values):
(SwiftCxxInteropTests.completionHandlerReceivesItsArgument):
(SwiftCxxInteropTests.wtfCompletionHandlerCanBeInvokedFromSwift):
(SwiftCxxInteropTests.completionHandlerPreservesCapturedState):
(SwiftCxxInteropTests.voidCompletionHandlerCanBeInvokedFromSwift):
(SwiftCxxInteropTests.voidCompletionHandlerWorksWithAContinuation):
(SwiftCxxInteropTests.separateHandlersDoNotShareAContext):
(SwiftCxxInteropTests.contextIsReleasedAfterTheHandlerIsCalled):
(SwiftCxxInteropTests.contextSurvivesUntilTheHandlerIsInvokedLater):
* Tools/TestWebKitAPI/Tests/WebKit/WebPage/JSHandleTests.swift:
* Tools/TestWebKitAPI/Tests/WebKit/WebPage/WebPageTests.swift:

Add tests
* Source/WTF/wtf/OptionSet.h:

Canonical link: https://commits.webkit.org/319901@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to