Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: d8a9b5a6e9815df71cc3a821ca8068bf425cd163
      
https://github.com/WebKit/WebKit/commit/d8a9b5a6e9815df71cc3a821ca8068bf425cd163
  Author: Elliott Williams <e...@apple.com>
  Date:   2024-11-19 (Tue, 19 Nov 2024)

  Changed paths:
    M Source/WebCore/Modules/WebGPU/GPUBuffer.cpp
    M Source/WebCore/Modules/WebGPU/Implementation/WebGPUBufferImpl.cpp
    M Source/WebCore/Modules/WebGPU/Implementation/WebGPUBufferImpl.h
    M Source/WebCore/Modules/WebGPU/InternalAPI/WebGPUBuffer.h
    M Source/WebGPU/Configurations/WebGPU.xcconfig
    M Source/WebGPU/WebGPU.xcodeproj/project.pbxproj
    M Source/WebGPU/WebGPU/Buffer.h
    M Source/WebGPU/WebGPU/Buffer.mm
    M Source/WebGPU/WebGPU/Buffer.swift
    M Source/WebGPU/WebGPU/CommandsMixin.h
    M Source/WebGPU/WebGPU/Internal/WebGPUSwiftInternal.h
    A Source/WebGPU/WebGPU/SwiftCXXThunk.h
    M Source/WebGPU/WebGPU/WebGPUExt.h
    R Source/WebGPU/WebGPU/WebGPUSwift.h
    M Source/WebKit/GPUProcess/graphics/WebGPU/RemoteBuffer.cpp
    M Source/WebKit/WebProcess/GPU/graphics/WebGPU/RemoteBufferProxy.cpp
    M Source/WebKit/WebProcess/GPU/graphics/WebGPU/RemoteBufferProxy.h

  Log Message:
  -----------
  [WebGPU] Support writing implementations of C++ members in Swift extensions
https://bugs.webkit.org/show_bug.cgi?id=283151
rdar://problem/139928444

Reviewed by Geoffrey Garen.

Swift does not currently have an equivalent of ObjC interop's
@implementation for C++ classes, i.e. a mechanism to implement a member
function of a C++ class in Swift. With some careful use of preprocessor
macros, provide an interface for shimming our way to a similar end. The
goal is for WebGPU member functions to be able to be written as Swift
extensions, with minimal overhead that can be cleaned up once
first-class support is available.

This is highly desirable for WebGPU, since it gives us a pathway to
reimplement bits of the project without affecting the overall WebGPU
class hierarchy, or resorting to awkward C-style object oriented
programming, where we only write free functions and have no
encapsulation rules to guard member access.

First, add a PUBLIC_IN_WEBGPU_SWIFT macro to modify encapsulation rules.
Swift's C++ interop layer only grants access to public members, even
in extensions. PUBLIC_IN_WEBGPU_SWIFT expands to `public` when compiling
WebGPU's swift module only, so it can be used to break encapsulation for
implementation purposes while preventing clients from accesing fields.

Second, introduce a pair of SWIFTCXX_THUNK macros to mark C++ member
functions that are implemented in Swift code. HAS_SWIFTCXX_THUNK
annotates a header declaration and indicates that the function is
refined by Swift. DEFINE_SWIFTCXX_THUNK generates a C++
member function that calls a Swift thunking function, which itself calls
the real extension member. The Swift thunk must be manually written. I
intend to add a Swift macro to generate the thunk in the future.

Putting it all together, reimplement WebGPU::Buffer::copy, attempting to
use idiomatic and memory-safe Swift. As a drive-by fix, rename it to
"copyFrom" to better reflect semantics. It works like this:

1. Buffer.h declares `copyFrom` as:

       void copyFrom(const std::span<const uint8_t>, const size_t offset) 
HAS_SWIFTCXX_THUNK;

   The NS_REFINED_FOR_SWIFT prevents Swift code from binding to this symbol
   and needlessly jumping through the thunks.

2. Buffer.mm implements the C++ thunk by providing the member name, its
   return type, and its argument types:

       SWIFTCXX_THUNK(WebGPU::Buffer, copyFrom, void, const std::span<const 
uint8_t>, const size_t);

3. The C++ thunk calls into a hand-written Swift thunk (this is what I
   intend to macro-ify in the future):

       public func Buffer_copyFrom_thunk(_ buffer: WebGPU.Buffer, from data: 
SpanConstUInt8, offset: Int) {
           buffer.copy(from: data, offset: offset)
       }

4. The Swift thunk calls into the actual extension code:

       extension WebGPU.Buffer {
           func copy(from data: SpanConstUInt8, offset: Int) {
               ...
           }
       }

   ...which has access to all members of WebGPU::Buffer that are marked
   PUBLIC_IN_WEBGPU_SWIFT.

These changes are all in service of the "copy" to "copyFrom" rename:

* Source/WebCore/Modules/WebGPU/GPUBuffer.cpp:
(WebCore::GPUBuffer::internalUnmap):
* Source/WebCore/Modules/WebGPU/Implementation/WebGPUBufferImpl.cpp:
(WebCore::WebGPU::BufferImpl::copyFrom):
(WebCore::WebGPU::BufferImpl::copy): Deleted.
* Source/WebCore/Modules/WebGPU/Implementation/WebGPUBufferImpl.h:
* Source/WebCore/Modules/WebGPU/InternalAPI/WebGPUBuffer.h:
* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteBuffer.cpp:
(WebKit::RemoteBuffer::copy):

The rest:

* Source/WebGPU/Configurations/WebGPU.xcconfig:
* Source/WebGPU/WebGPU.xcodeproj/project.pbxproj:
* Source/WebGPU/WebGPU/Buffer.h:
* Source/WebGPU/WebGPU/Buffer.mm:
(wgpuBufferCopy):
(WebGPU::Buffer::copy): Deleted.
* Source/WebGPU/WebGPU/Buffer.swift:
(WebGPU.bufferContents):
(WebGPU.copy(from:offset:)):
(Buffer_copyFrom_thunk(_:from:offset:)):
(copySpan(_:source:)): Deleted.
* Source/WebGPU/WebGPU/CommandsMixin.h:
* Source/WebGPU/WebGPU/Internal/WebGPUSwiftInternal.h:
* Source/WebGPU/WebGPU/SwiftCXXThunk.h: Added.
* Source/WebGPU/WebGPU/WebGPUExt.h:
* Source/WebGPU/WebGPU/WebGPUSwift.h: Removed. I thought I would need it
  in <https://commits.webkit.org/286661@main>, but WebGPUExt.h is a
  better home for declarations that need to be included everywhere.

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



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to