Skip to content

Commit 758cb4e

Browse files
Merge pull request #222 from GoodNotes/withUnsafeBytesAsync
Add `withUnsafeBytesAsync` function to `JSTypedArray`
2 parents 59e7b65 + 8fbe91d commit 758cb4e

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

Diff for: .github/workflows/test.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ jobs:
1010
matrix:
1111
entry:
1212
# Ensure that all host can install toolchain, build project, and run tests
13-
- { os: macos-10.15, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node }
14-
- { os: macos-11, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node }
15-
- { os: macos-12, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node }
13+
- { os: macos-10.15, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node, xcode: Xcode_12.4.app }
14+
- { os: macos-11, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node, xcode: Xcode_13.2.1.app }
15+
- { os: macos-12, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node, xcode: Xcode_13.4.1.app }
1616
- { os: ubuntu-18.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node }
1717

1818
# Ensure that test succeeds with all toolchains and wasi backend combinations
@@ -33,6 +33,9 @@ jobs:
3333
uses: actions/checkout@master
3434
with:
3535
fetch-depth: 1
36+
- name: Select SDKROOT
37+
if: ${{ matrix.entry.xcode }}
38+
run: sudo xcode-select -s /Applications/${{ matrix.entry.xcode }}
3639
- uses: swiftwasm/setup-swiftwasm@v1
3740
with:
3841
swift-version: ${{ matrix.entry.toolchain }}

Diff for: Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift

+28
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,34 @@ public class JSTypedArray<Element>: JSBridgedClass, ExpressibleByArrayLiteral wh
8888
let result = try body(bufferPtr)
8989
return result
9090
}
91+
92+
#if compiler(>=5.5)
93+
/// Calls the given async closure with a pointer to a copy of the underlying bytes of the
94+
/// array's storage.
95+
///
96+
/// - Note: The pointer passed as an argument to `body` is valid only for the
97+
/// lifetime of the closure. Do not escape it from the async closure for later
98+
/// use.
99+
///
100+
/// - Parameter body: A closure with an `UnsafeBufferPointer` parameter
101+
/// that points to the contiguous storage for the array.
102+
/// If `body` has a return value, that value is also
103+
/// used as the return value for the `withUnsafeBytes(_:)` method. The
104+
/// argument is valid only for the duration of the closure's execution.
105+
/// - Returns: The return value, if any, of the `body`async closure parameter.
106+
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
107+
public func withUnsafeBytesAsync<R>(_ body: (UnsafeBufferPointer<Element>) async throws -> R) async rethrows -> R {
108+
let bytesLength = lengthInBytes
109+
let rawBuffer = malloc(bytesLength)!
110+
defer { free(rawBuffer) }
111+
_load_typed_array(jsObject.id, rawBuffer.assumingMemoryBound(to: UInt8.self))
112+
let length = lengthInBytes / MemoryLayout<Element>.size
113+
let boundPtr = rawBuffer.bindMemory(to: Element.self, capacity: length)
114+
let bufferPtr = UnsafeBufferPointer<Element>(start: boundPtr, count: length)
115+
let result = try await body(bufferPtr)
116+
return result
117+
}
118+
#endif
91119
}
92120

93121
// MARK: - Int and UInt support

0 commit comments

Comments
 (0)