diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c803379ce..c129040f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,22 +10,20 @@ jobs: matrix: entry: # Ensure that all host can install toolchain, build project, and run tests - - { os: macos-11, toolchain: wasm-5.8.0-RELEASE, wasi-backend: Node, xcode: Xcode_13.2.1.app } - - { os: macos-12, toolchain: wasm-5.8.0-RELEASE, wasi-backend: Node, xcode: Xcode_13.4.1.app } - - { os: macos-13, toolchain: wasm-5.8.0-RELEASE, wasi-backend: Node, xcode: Xcode_14.3.app } - - { os: ubuntu-22.04, toolchain: wasm-5.8.0-RELEASE, wasi-backend: Node } + - { os: macos-11, toolchain: wasm-5.9-SNAPSHOT-2024-01-12-a, wasi-backend: Node, xcode: Xcode_13.2.1.app } + - { os: macos-12, toolchain: wasm-5.9-SNAPSHOT-2024-01-12-a, wasi-backend: Node, xcode: Xcode_13.4.1.app } + - { os: macos-13, toolchain: wasm-5.9-SNAPSHOT-2024-01-12-a, wasi-backend: Node, xcode: Xcode_14.3.app } + - { os: ubuntu-22.04, toolchain: wasm-5.9-SNAPSHOT-2024-01-12-a, wasi-backend: Node } # Ensure that test succeeds with all toolchains and wasi backend combinations - - { os: ubuntu-20.04, toolchain: wasm-5.5.0-RELEASE, wasi-backend: Node } - - { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } - { os: ubuntu-20.04, toolchain: wasm-5.7.3-RELEASE, wasi-backend: Node } - { os: ubuntu-20.04, toolchain: wasm-5.8.0-RELEASE, wasi-backend: Node } - - { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Wasmer } - { os: ubuntu-20.04, toolchain: wasm-5.7.3-RELEASE, wasi-backend: Wasmer } - { os: ubuntu-20.04, toolchain: wasm-5.8.0-RELEASE, wasi-backend: Wasmer } - - { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: MicroWASI } + - { os: ubuntu-20.04, toolchain: wasm-5.9-SNAPSHOT-2024-01-12-a, wasi-backend: Wasmer } - { os: ubuntu-20.04, toolchain: wasm-5.7.3-RELEASE, wasi-backend: MicroWASI } - { os: ubuntu-20.04, toolchain: wasm-5.8.0-RELEASE, wasi-backend: MicroWASI } + - { os: ubuntu-20.04, toolchain: wasm-5.9-SNAPSHOT-2024-01-12-a, wasi-backend: MicroWASI } runs-on: ${{ matrix.entry.os }} env: @@ -45,7 +43,9 @@ jobs: - run: make bootstrap - run: make test - run: make unittest - if: ${{ startsWith(matrix.toolchain, 'wasm-5.7.') }} + # Skip unit tests with uwasi because its proc_exit throws + # unhandled promise rejection. + if: ${{ matrix.entry.wasi-backend != 'MicroWASI' }} - name: Check if SwiftPM resources are stale run: | make regenerate_swiftpm_resources diff --git a/IntegrationTests/TestSuites/Sources/ConcurrencyTests/UnitTestUtils.swift b/IntegrationTests/TestSuites/Sources/ConcurrencyTests/UnitTestUtils.swift index 40c3165da..acd81e6d9 100644 --- a/IntegrationTests/TestSuites/Sources/ConcurrencyTests/UnitTestUtils.swift +++ b/IntegrationTests/TestSuites/Sources/ConcurrencyTests/UnitTestUtils.swift @@ -15,6 +15,7 @@ func test(_ name: String, testBlock: () throws -> Void) throws { print(error) throw error } + print("✅ \(name)") } func asyncTest(_ name: String, testBlock: () async throws -> Void) async throws -> Void { @@ -26,6 +27,7 @@ func asyncTest(_ name: String, testBlock: () async throws -> Void) async throws print(error) throw error } + print("✅ \(name)") } struct MessageError: Error { diff --git a/IntegrationTests/TestSuites/Sources/ConcurrencyTests/main.swift b/IntegrationTests/TestSuites/Sources/ConcurrencyTests/main.swift index c80e48779..ece58b317 100644 --- a/IntegrationTests/TestSuites/Sources/ConcurrencyTests/main.swift +++ b/IntegrationTests/TestSuites/Sources/ConcurrencyTests/main.swift @@ -6,10 +6,8 @@ import WASILibc import Darwin #endif -#if compiler(>=5.5) - func performanceNow() -> Double { - return JSObject.global.performance.now.function!().number! + return JSObject.global.performance.now().number! } func measure(_ block: () async throws -> Void) async rethrows -> Double { @@ -213,32 +211,6 @@ func entrypoint() async throws { #endif } - -// Note: Please define `USE_SWIFT_TOOLS_VERSION_NEWER_THAN_5_5` if the swift-tools-version is newer -// than 5.5 to avoid the linking issue. -#if USE_SWIFT_TOOLS_VERSION_NEWER_THAN_5_5 -// Workaround: The latest SwiftPM rename main entry point name of executable target -// to avoid conflicting "main" with test target since `swift-tools-version >= 5.5`. -// The main symbol is renamed to "{{module_name}}_main" and it's renamed again to be -// "main" when linking the executable target. The former renaming is done by Swift compiler, -// and the latter is done by linker, so SwiftPM passes some special linker flags for each platform. -// But SwiftPM assumes that wasm-ld supports it by returning an empty array instead of nil even though -// wasm-ld doesn't support it yet. -// ref: https://github.com/apple/swift-package-manager/blob/1be68e811d0d814ba7abbb8effee45f1e8e6ec0d/Sources/Build/BuildPlan.swift#L117-L126 -// So define an explicit "main" by @_cdecl -@_cdecl("main") -func main(argc: Int32, argv: Int32) -> Int32 { - JavaScriptEventLoop.installGlobalExecutor() - Task { - do { - try await entrypoint() - } catch { - print(error) - } - } - return 0 -} -#else JavaScriptEventLoop.installGlobalExecutor() Task { do { @@ -247,8 +219,3 @@ Task { print(error) } } - -#endif - - -#endif diff --git a/IntegrationTests/lib.js b/IntegrationTests/lib.js index e708816cb..1d7b6342d 100644 --- a/IntegrationTests/lib.js +++ b/IntegrationTests/lib.js @@ -64,6 +64,7 @@ const WASI = { args: [programName], env: {}, returnOnExit: false, + version: "preview1", }) return { diff --git a/IntegrationTests/package-lock.json b/IntegrationTests/package-lock.json index cc6ed8de9..8ccbcdc21 100644 --- a/IntegrationTests/package-lock.json +++ b/IntegrationTests/package-lock.json @@ -8,12 +8,12 @@ "@wasmer/wasi": "^0.12.0", "@wasmer/wasmfs": "^0.12.0", "javascript-kit-swift": "file:..", - "uwasi": "^1.0.0" + "uwasi": "^1.2.0" } }, "..": { "name": "javascript-kit-swift", - "version": "0.14.0", + "version": "0.18.0", "license": "MIT", "devDependencies": { "@rollup/plugin-typescript": "^8.3.1", @@ -219,9 +219,9 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "node_modules/uwasi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uwasi/-/uwasi-1.0.0.tgz", - "integrity": "sha512-xnjYEegIsUDh7aXnT6s+pNK79adEQs5R+T+fds/fFdCEtoKFkH3ngwbp3jAJjB91VfPgOVUKIH+fNbg6Om8xAw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/uwasi/-/uwasi-1.2.0.tgz", + "integrity": "sha512-+U3ajjQgx/Xh1/ZNrgH0EzM5qI2czr94oz3DPDwTvUIlM4SFpDjTqJzDA3xcqlTmpp2YGpxApmjwZfablMUoOg==" }, "node_modules/wrappy": { "version": "1.0.2", @@ -400,9 +400,9 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uwasi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uwasi/-/uwasi-1.0.0.tgz", - "integrity": "sha512-xnjYEegIsUDh7aXnT6s+pNK79adEQs5R+T+fds/fFdCEtoKFkH3ngwbp3jAJjB91VfPgOVUKIH+fNbg6Om8xAw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/uwasi/-/uwasi-1.2.0.tgz", + "integrity": "sha512-+U3ajjQgx/Xh1/ZNrgH0EzM5qI2czr94oz3DPDwTvUIlM4SFpDjTqJzDA3xcqlTmpp2YGpxApmjwZfablMUoOg==" }, "wrappy": { "version": "1.0.2", diff --git a/IntegrationTests/package.json b/IntegrationTests/package.json index 3458b7385..a7d756165 100644 --- a/IntegrationTests/package.json +++ b/IntegrationTests/package.json @@ -3,7 +3,7 @@ "dependencies": { "@wasmer/wasi": "^0.12.0", "@wasmer/wasmfs": "^0.12.0", - "uwasi": "^1.0.0", + "uwasi": "^1.2.0", "javascript-kit-swift": "file:.." } } diff --git a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift index 72dc8f503..7f7e69971 100644 --- a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift +++ b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift @@ -122,13 +122,25 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable { private func enqueue(_ job: UnownedJob, withDelay nanoseconds: UInt64) { let milliseconds = nanoseconds / 1_000_000 setTimeout(Double(milliseconds), { + #if compiler(>=5.9) + job.runSynchronously(on: self.asUnownedSerialExecutor()) + #else job._runSynchronously(on: self.asUnownedSerialExecutor()) + #endif }) } + #if compiler(>=5.9) + public func enqueue(_ job: consuming ExecutorJob) { + // NOTE: Converting a `ExecutorJob` to an ``UnownedJob`` and invoking + // ``UnownedJob/runSynchronously(_:)` on it multiple times is undefined behavior. + insertJobQueue(job: UnownedJob(job)) + } + #else public func enqueue(_ job: UnownedJob) { insertJobQueue(job: job) } + #endif public func asUnownedSerialExecutor() -> UnownedSerialExecutor { return UnownedSerialExecutor(ordinary: self) diff --git a/Sources/JavaScriptEventLoop/JobQueue.swift b/Sources/JavaScriptEventLoop/JobQueue.swift index 44b2f7249..6cc0cfc35 100644 --- a/Sources/JavaScriptEventLoop/JobQueue.swift +++ b/Sources/JavaScriptEventLoop/JobQueue.swift @@ -43,7 +43,11 @@ extension JavaScriptEventLoop { assert(queueState.isSpinning) while let job = self.claimNextFromQueue() { + #if compiler(>=5.9) + job.runSynchronously(on: self.asUnownedSerialExecutor()) + #else job._runSynchronously(on: self.asUnownedSerialExecutor()) + #endif } queueState.isSpinning = false