diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d41966fe3..655da183e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,9 +10,9 @@ jobs: matrix: entry: # Ensure that all host can install toolchain, build project, and run tests - - { os: macos-10.15, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } - - { os: macos-11, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } - - { os: macos-12, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } + - { os: macos-10.15, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node, xcode: Xcode_12.4.app } + - { os: macos-11, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node, xcode: Xcode_13.2.1.app } + - { os: macos-12, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node, xcode: Xcode_13.4.1.app } - { os: ubuntu-18.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } # Ensure that test succeeds with all toolchains and wasi backend combinations @@ -33,6 +33,9 @@ jobs: uses: actions/checkout@master with: fetch-depth: 1 + - name: Select SDKROOT + if: ${{ matrix.entry.xcode }} + run: sudo xcode-select -s /Applications/${{ matrix.entry.xcode }} - uses: swiftwasm/setup-swiftwasm@v1 with: swift-version: ${{ matrix.entry.toolchain }} diff --git a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift index c22e6c8cc..f82864e86 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift @@ -88,6 +88,34 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh let result = try body(bufferPtr) return result } + + #if compiler(>=5.5) + /// Calls the given async closure with a pointer to a copy of the underlying bytes of the + /// array's storage. + /// + /// - Note: The pointer passed as an argument to `body` is valid only for the + /// lifetime of the closure. Do not escape it from the async closure for later + /// use. + /// + /// - Parameter body: A closure with an `UnsafeBufferPointer` parameter + /// that points to the contiguous storage for the array. + /// If `body` has a return value, that value is also + /// used as the return value for the `withUnsafeBytes(_:)` method. The + /// argument is valid only for the duration of the closure's execution. + /// - Returns: The return value, if any, of the `body`async closure parameter. + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func withUnsafeBytesAsync(_ body: (UnsafeBufferPointer) async throws -> R) async rethrows -> R { + let bytesLength = lengthInBytes + let rawBuffer = malloc(bytesLength)! + defer { free(rawBuffer) } + _load_typed_array(jsObject.id, rawBuffer.assumingMemoryBound(to: UInt8.self)) + let length = lengthInBytes / MemoryLayout.size + let boundPtr = rawBuffer.bindMemory(to: Element.self, capacity: length) + let bufferPtr = UnsafeBufferPointer(start: boundPtr, count: length) + let result = try await body(bufferPtr) + return result + } + #endif } // MARK: - Int and UInt support