Skip to content

Commit ea06982

Browse files
Add sharedMemory option to allow threads with shared memory (#247)
* Add `sharedMemory` option to allow threads with shared memory * Enable thread enabled Swift SDK testing in CI * Support shared memory in test harness * Don't use symlink directory in the path of the program name This is a workaround for the issue that the argv0 program path containing a symlink directory in the path causes `Bundle.main` to crash.
1 parent 8449f87 commit ea06982

File tree

6 files changed

+551
-475
lines changed

6 files changed

+551
-475
lines changed

.github/workflows/test.yml

+6-7
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ jobs:
2727
id: DEVELOPMENT-SNAPSHOT-2024-05-25-a-wasm32-unknown-wasi
2828
download-url: "https://github.com/swiftwasm/swift/releases/download/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-05-25-a/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-05-25-a-wasm32-unknown-wasi.artifactbundle.zip"
2929
wasi-backend: Node
30-
# TODO: Enable this once we support threads in JavaScriptKit
31-
# - os: ubuntu-22.04
32-
# toolchain: DEVELOPMENT-SNAPSHOT-2024-05-01-a
33-
# swift-sdk:
34-
# id: DEVELOPMENT-SNAPSHOT-2024-05-25-a-wasm32-unknown-wasip1-threads
35-
# download-url: "https://github.com/swiftwasm/swift/releases/download/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-05-25-a/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-05-25-a-wasm32-unknown-wasip1-threads.artifactbundle.zip"
36-
# wasi-backend: Node
30+
- os: ubuntu-22.04
31+
toolchain: DEVELOPMENT-SNAPSHOT-2024-05-01-a
32+
swift-sdk:
33+
id: DEVELOPMENT-SNAPSHOT-2024-05-25-a-wasm32-unknown-wasip1-threads
34+
download-url: "https://github.com/swiftwasm/swift/releases/download/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-05-25-a/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-05-25-a-wasm32-unknown-wasip1-threads.artifactbundle.zip"
35+
wasi-backend: Node
3736

3837
runs-on: ${{ matrix.entry.os }}
3938
env:

IntegrationTests/lib.js

+34-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import { SwiftRuntime } from "javascript-kit-swift"
22
import { WASI as NodeWASI } from "wasi"
33
import { WASI as MicroWASI, useAll } from "uwasi"
44
import * as fs from "fs/promises"
5+
import path from "path";
56

67
const WASI = {
78
MicroWASI: ({ programName }) => {
89
const wasi = new MicroWASI({
9-
args: [programName],
10+
args: [path.basename(programName)],
1011
env: {},
1112
features: [useAll()],
1213
})
@@ -21,7 +22,7 @@ const WASI = {
2122
},
2223
Node: ({ programName }) => {
2324
const wasi = new NodeWASI({
24-
args: [programName],
25+
args: [path.basename(programName)],
2526
env: {},
2627
preopens: {
2728
"/": "./",
@@ -51,21 +52,49 @@ const selectWASIBackend = () => {
5152
return WASI.Node;
5253
};
5354

55+
function isUsingSharedMemory(module) {
56+
const imports = WebAssembly.Module.imports(module);
57+
for (const entry of imports) {
58+
if (entry.module === "env" && entry.name === "memory" && entry.kind == "memory") {
59+
return true;
60+
}
61+
}
62+
return false;
63+
}
64+
5465
export const startWasiTask = async (wasmPath, wasiConstructor = selectWASIBackend()) => {
5566
const swift = new SwiftRuntime();
5667
// Fetch our Wasm File
5768
const wasmBinary = await fs.readFile(wasmPath);
5869
const wasi = wasiConstructor({ programName: wasmPath });
5970

60-
// Instantiate the WebAssembly file
61-
let { instance } = await WebAssembly.instantiate(wasmBinary, {
71+
const module = await WebAssembly.compile(wasmBinary);
72+
73+
const importObject = {
6274
wasi_snapshot_preview1: wasi.wasiImport,
6375
javascript_kit: swift.importObjects(),
6476
benchmark_helper: {
6577
noop: () => {},
6678
noop_with_int: (_) => {},
6779
}
68-
});
80+
};
81+
82+
if (isUsingSharedMemory(module)) {
83+
importObject["env"] = {
84+
// We don't have JS API to get memory descriptor of imported memory
85+
// at this moment, so we assume 256 pages (16MB) memory is enough
86+
// large for initial memory size.
87+
memory: new WebAssembly.Memory({ initial: 256, maximum: 16384, shared: true }),
88+
};
89+
importObject["wasi"] = {
90+
"thread-spawn": () => {
91+
throw new Error("thread-spawn not implemented");
92+
}
93+
}
94+
}
95+
96+
// Instantiate the WebAssembly file
97+
const instance = await WebAssembly.instantiate(module, importObject);
6998

7099
swift.setInstance(instance);
71100
// Start the WebAssembly WASI instance!

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ test:
2828
unittest:
2929
@echo Running unit tests
3030
swift build --build-tests -Xswiftc -Xclang-linker -Xswiftc -mexec-model=reactor -Xlinker --export-if-defined=main -Xlinker --export-if-defined=__main_argc_argv --static-swift-stdlib -Xswiftc -static-stdlib $(SWIFT_BUILD_FLAGS)
31-
node --experimental-wasi-unstable-preview1 scripts/test-harness.mjs ./.build/wasm32-unknown-wasi/debug/JavaScriptKitPackageTests.wasm
31+
node --experimental-wasi-unstable-preview1 scripts/test-harness.mjs ./.build/debug/JavaScriptKitPackageTests.wasm
3232

3333
.PHONY: benchmark_setup
3434
benchmark_setup:

0 commit comments

Comments
 (0)