Skip to content

Commit aacf993

Browse files
committed
test: wpt for Wasm jsapi including new ESM Integration tests
1 parent a472745 commit aacf993

37 files changed

+649
-4
lines changed

test/common/wpt.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ class WPTRunner {
885885
console.log(test.stack);
886886
}
887887
const command = `${process.execPath} ${process.execArgv}` +
888-
` ${require.main.filename} '${spec.filename}${spec.variant}'`;
888+
` ${require.main?.filename} '${spec.filename}${spec.variant}'`;
889889
console.log(`Command: ${command}\n`);
890890

891891
reportResult?.addSubtest(test.name, 'FAIL', test.message);

test/common/wpt/worker.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
'use strict';
22

3-
const { runInNewContext, runInThisContext } = require('vm');
3+
const {
4+
runInNewContext,
5+
runInThisContext,
6+
constants: { USE_MAIN_CONTEXT_DEFAULT_LOADER },
7+
} = require('vm');
48
const { setFlagsFromString } = require('v8');
59
const { parentPort, workerData } = require('worker_threads');
610

@@ -28,11 +32,14 @@ globalThis.fetch = function fetch(file) {
2832
};
2933

3034
if (workerData.initScript) {
31-
runInThisContext(workerData.initScript);
35+
runInThisContext(workerData.initScript, {
36+
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER,
37+
});
3238
}
3339

3440
runInThisContext(workerData.harness.code, {
3541
filename: workerData.harness.filename,
42+
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER,
3643
});
3744

3845
// eslint-disable-next-line no-undef
@@ -66,5 +73,8 @@ add_completion_callback((_, status) => {
6673
});
6774

6875
for (const scriptToRun of workerData.scriptsToRun) {
69-
runInThisContext(scriptToRun.code, { filename: scriptToRun.filename });
76+
runInThisContext(scriptToRun.code, {
77+
filename: scriptToRun.filename,
78+
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER,
79+
});
7080
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// META: global=window,dedicatedworker,jsshell,shadowrealm
2+
3+
"use strict";
4+
5+
promise_test(async () => {
6+
const mod = await import("./resources/exports.wasm");
7+
8+
assert_array_equals(Object.getOwnPropertyNames(mod).sort(), [
9+
"a\u200Bb\u0300c",
10+
"func",
11+
"glob",
12+
"mem",
13+
"tab",
14+
"value with spaces",
15+
"🎯test-func!",
16+
]);
17+
assert_true(mod.func instanceof Function);
18+
assert_true(mod.mem instanceof WebAssembly.Memory);
19+
assert_true(mod.tab instanceof WebAssembly.Table);
20+
21+
assert_false(mod.glob instanceof WebAssembly.Global);
22+
assert_equals(typeof mod.glob, "number");
23+
24+
assert_throws_js(TypeError, () => {
25+
mod.func = 2;
26+
});
27+
28+
assert_equals(typeof mod["value with spaces"], "number");
29+
assert_equals(mod["value with spaces"], 123);
30+
31+
assert_true(mod["🎯test-func!"] instanceof Function);
32+
assert_equals(mod["🎯test-func!"](), 456);
33+
34+
assert_equals(typeof mod["a\u200Bb\u0300c"], "number");
35+
assert_equals(mod["a\u200Bb\u0300c"], 789);
36+
}, "Exported names from a WebAssembly module");
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// META: global=window,dedicatedworker,jsshell,shadowrealm
2+
3+
promise_test(async () => {
4+
const wasmExports = await import("./resources/globals.wasm");
5+
6+
wasmExports.setLocalMutI32(555);
7+
assert_equals(wasmExports.getLocalMutI32(), 555);
8+
assert_equals(wasmExports.localMutI32, 555);
9+
10+
wasmExports.setLocalMutI64(444n);
11+
assert_equals(wasmExports.getLocalMutI64(), 444n);
12+
assert_equals(wasmExports.localMutI64, 444n);
13+
14+
wasmExports.setLocalMutF32(3.33);
15+
assert_equals(Math.round(wasmExports.getLocalMutF32() * 100) / 100, 3.33);
16+
assert_equals(Math.round(wasmExports.localMutF32 * 100) / 100, 3.33);
17+
18+
wasmExports.setLocalMutF64(2.22);
19+
assert_equals(wasmExports.getLocalMutF64(), 2.22);
20+
assert_equals(wasmExports.localMutF64, 2.22);
21+
22+
const anotherTestObj = { another: "test object" };
23+
wasmExports.setLocalMutExternref(anotherTestObj);
24+
assert_equals(wasmExports.getLocalMutExternref(), anotherTestObj);
25+
assert_equals(wasmExports.localMutExternref, anotherTestObj);
26+
}, "Local mutable global exports should be live bindings");
27+
28+
promise_test(async () => {
29+
const wasmExports = await import("./resources/globals.wasm");
30+
31+
wasmExports.setDepMutI32(3001);
32+
assert_equals(wasmExports.getDepMutI32(), 3001);
33+
assert_equals(wasmExports.depMutI32, 3001);
34+
35+
wasmExports.setDepMutI64(30000000001n);
36+
assert_equals(wasmExports.getDepMutI64(), 30000000001n);
37+
assert_equals(wasmExports.depMutI64, 30000000001n);
38+
39+
wasmExports.setDepMutF32(30.01);
40+
assert_equals(Math.round(wasmExports.getDepMutF32() * 100) / 100, 30.01);
41+
assert_equals(Math.round(wasmExports.depMutF32 * 100) / 100, 30.01);
42+
43+
wasmExports.setDepMutF64(300.0001);
44+
assert_equals(wasmExports.getDepMutF64(), 300.0001);
45+
assert_equals(wasmExports.depMutF64, 300.0001);
46+
}, "Dep module mutable global exports should be live bindings");
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// META: global=window,dedicatedworker,jsshell,shadowrealm
2+
3+
promise_test(async () => {
4+
const wasmModule = await import("./resources/globals.wasm");
5+
6+
assert_equals(wasmModule.importedI32, 42);
7+
assert_equals(wasmModule.importedI64, 9223372036854775807n);
8+
assert_equals(Math.round(wasmModule.importedF32 * 100000) / 100000, 3.14159);
9+
assert_equals(wasmModule.importedF64, 3.141592653589793);
10+
assert_not_equals(wasmModule.importedExternref, null);
11+
assert_equals(wasmModule.importedNullExternref, null);
12+
}, "WebAssembly module global values should be unwrapped when importing in ESM integration");
13+
14+
promise_test(async () => {
15+
const wasmModule = await import("./resources/globals.wasm");
16+
17+
assert_equals(wasmModule.importedMutI32, 100);
18+
assert_equals(wasmModule.importedMutI64, 200n);
19+
assert_equals(
20+
Math.round(wasmModule.importedMutF32 * 100000) / 100000,
21+
2.71828
22+
);
23+
assert_equals(wasmModule.importedMutF64, 2.718281828459045);
24+
assert_not_equals(wasmModule.importedMutExternref, null);
25+
assert_equals(wasmModule.importedMutExternref.mutable, "global");
26+
}, "WebAssembly mutable global values should be unwrapped when importing in ESM integration");
27+
28+
promise_test(async () => {
29+
const wasmModule = await import("./resources/globals.wasm");
30+
31+
assert_equals(wasmModule["🚀localI32"], 42);
32+
assert_equals(wasmModule.localMutI32, 100);
33+
assert_equals(wasmModule.localI64, 9223372036854775807n);
34+
assert_equals(wasmModule.localMutI64, 200n);
35+
assert_equals(Math.round(wasmModule.localF32 * 100000) / 100000, 3.14159);
36+
assert_equals(Math.round(wasmModule.localMutF32 * 100000) / 100000, 2.71828);
37+
assert_equals(wasmModule.localF64, 2.718281828459045);
38+
assert_equals(wasmModule.localMutF64, 3.141592653589793);
39+
}, "WebAssembly local global values should be unwrapped when exporting in ESM integration");
40+
41+
promise_test(async () => {
42+
const wasmModule = await import("./resources/globals.wasm");
43+
44+
assert_equals(wasmModule.depI32, 1001);
45+
assert_equals(wasmModule.depMutI32, 2001);
46+
assert_equals(wasmModule.depI64, 10000000001n);
47+
assert_equals(wasmModule.depMutI64, 20000000001n);
48+
assert_equals(Math.round(wasmModule.depF32 * 100) / 100, 10.01);
49+
assert_equals(Math.round(wasmModule.depMutF32 * 100) / 100, 20.01);
50+
assert_equals(wasmModule.depF64, 100.0001);
51+
assert_equals(wasmModule.depMutF64, 200.0001);
52+
}, "WebAssembly module globals from imported WebAssembly modules should be unwrapped");
53+
54+
promise_test(async () => {
55+
const wasmModule = await import("./resources/globals.wasm");
56+
57+
assert_equals(wasmModule.importedI32, 42);
58+
assert_equals(wasmModule.importedMutI32, 100);
59+
assert_equals(wasmModule.importedI64, 9223372036854775807n);
60+
assert_equals(wasmModule.importedMutI64, 200n);
61+
assert_equals(Math.round(wasmModule.importedF32 * 100000) / 100000, 3.14159);
62+
assert_equals(
63+
Math.round(wasmModule.importedMutF32 * 100000) / 100000,
64+
2.71828
65+
);
66+
assert_equals(wasmModule.importedF64, 3.141592653589793);
67+
assert_equals(wasmModule.importedMutF64, 2.718281828459045);
68+
assert_equals(wasmModule.importedExternref !== null, true);
69+
assert_equals(wasmModule.importedMutExternref !== null, true);
70+
assert_equals(wasmModule.importedNullExternref, null);
71+
72+
assert_equals(wasmModule["🚀localI32"], 42);
73+
assert_equals(wasmModule.localMutI32, 100);
74+
assert_equals(wasmModule.localI64, 9223372036854775807n);
75+
assert_equals(wasmModule.localMutI64, 200n);
76+
assert_equals(Math.round(wasmModule.localF32 * 100000) / 100000, 3.14159);
77+
assert_equals(Math.round(wasmModule.localMutF32 * 100000) / 100000, 2.71828);
78+
assert_equals(wasmModule.localF64, 2.718281828459045);
79+
assert_equals(wasmModule.localMutF64, 3.141592653589793);
80+
81+
assert_equals(wasmModule.getImportedMutI32(), 100);
82+
assert_equals(wasmModule.getImportedMutI64(), 200n);
83+
assert_equals(
84+
Math.round(wasmModule.getImportedMutF32() * 100000) / 100000,
85+
2.71828
86+
);
87+
assert_equals(wasmModule.getImportedMutF64(), 2.718281828459045);
88+
assert_equals(wasmModule.getImportedMutExternref() !== null, true);
89+
90+
assert_equals(wasmModule.getLocalMutI32(), 100);
91+
assert_equals(wasmModule.getLocalMutI64(), 200n);
92+
assert_equals(
93+
Math.round(wasmModule.getLocalMutF32() * 100000) / 100000,
94+
2.71828
95+
);
96+
assert_equals(wasmModule.getLocalMutF64(), 3.141592653589793);
97+
assert_equals(wasmModule.getLocalMutExternref(), null);
98+
99+
assert_equals(wasmModule.depI32, 1001);
100+
assert_equals(wasmModule.depMutI32, 2001);
101+
assert_equals(wasmModule.getDepMutI32(), 2001);
102+
assert_equals(wasmModule.depI64, 10000000001n);
103+
assert_equals(wasmModule.depMutI64, 20000000001n);
104+
assert_equals(wasmModule.getDepMutI64(), 20000000001n);
105+
assert_equals(Math.round(wasmModule.depF32 * 100) / 100, 10.01);
106+
assert_equals(Math.round(wasmModule.depMutF32 * 100) / 100, 20.01);
107+
assert_equals(Math.round(wasmModule.getDepMutF32() * 100) / 100, 20.01);
108+
assert_equals(wasmModule.depF64, 100.0001);
109+
assert_equals(wasmModule.depMutF64, 200.0001);
110+
assert_equals(wasmModule.getDepMutF64(), 200.0001);
111+
}, "WebAssembly should properly handle all global types");
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// META: global=window,dedicatedworker,jsshell,shadowrealm
2+
3+
promise_test(async () => {
4+
const { f } = await import("./resources/js-wasm-cycle.js");
5+
6+
assert_equals(f(), 24);
7+
}, "Check bindings in JavaScript and WebAssembly cycle (JS higher)");
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
promise_test(async () => {
2+
const exporterModule = await import("./resources/mutable-global-export.wasm");
3+
const reexporterModule = await import(
4+
"./resources/mutable-global-reexport.wasm"
5+
);
6+
7+
assert_equals(exporterModule.mutableValue, 100);
8+
assert_equals(reexporterModule.reexportedMutableValue, 100);
9+
}, "WebAssembly modules should export shared mutable globals with correct initial values");
10+
11+
promise_test(async () => {
12+
const exporterModule = await import("./resources/mutable-global-export.wasm");
13+
const reexporterModule = await import(
14+
"./resources/mutable-global-reexport.wasm"
15+
);
16+
17+
exporterModule.setGlobal(500);
18+
19+
assert_equals(exporterModule.getGlobal(), 500, "exporter should see 500");
20+
assert_equals(reexporterModule.getImportedGlobal(), 500);
21+
22+
reexporterModule.setImportedGlobal(600);
23+
24+
assert_equals(exporterModule.getGlobal(), 600);
25+
assert_equals(reexporterModule.getImportedGlobal(), 600);
26+
27+
exporterModule.setGlobal(700);
28+
29+
assert_equals(exporterModule.getGlobal(), 700);
30+
assert_equals(reexporterModule.getImportedGlobal(), 700);
31+
}, "Wasm-to-Wasm mutable global sharing is live");
32+
33+
promise_test(async () => {
34+
const module1 = await import("./resources/mutable-global-export.wasm");
35+
const module2 = await import("./resources/mutable-global-export.wasm");
36+
37+
assert_equals(module1, module2);
38+
39+
module1.setGlobal(800);
40+
assert_equals(module1.getGlobal(), 800, "module1 should see its own change");
41+
assert_equals(module2.getGlobal(), 800);
42+
}, "Multiple JavaScript imports return the same WebAssembly module instance");
43+
44+
promise_test(async () => {
45+
const exporterModule = await import("./resources/mutable-global-export.wasm");
46+
const reexporterModule = await import(
47+
"./resources/mutable-global-reexport.wasm"
48+
);
49+
50+
assert_equals(exporterModule.getV128Lane(0), 1);
51+
assert_equals(exporterModule.getV128Lane(1), 2);
52+
assert_equals(exporterModule.getV128Lane(2), 3);
53+
assert_equals(exporterModule.getV128Lane(3), 4);
54+
55+
assert_equals(reexporterModule.getImportedV128Lane(0), 1);
56+
assert_equals(reexporterModule.getImportedV128Lane(1), 2);
57+
assert_equals(reexporterModule.getImportedV128Lane(2), 3);
58+
assert_equals(reexporterModule.getImportedV128Lane(3), 4);
59+
}, "v128 globals should work correctly in WebAssembly-to-WebAssembly imports");
60+
61+
promise_test(async () => {
62+
const exporterModule = await import("./resources/mutable-global-export.wasm");
63+
const reexporterModule = await import(
64+
"./resources/mutable-global-reexport.wasm"
65+
);
66+
67+
exporterModule.setV128Global(10, 20, 30, 40);
68+
69+
assert_equals(exporterModule.getV128Lane(0), 10);
70+
assert_equals(exporterModule.getV128Lane(1), 20);
71+
assert_equals(exporterModule.getV128Lane(2), 30);
72+
assert_equals(exporterModule.getV128Lane(3), 40);
73+
74+
assert_equals(reexporterModule.getImportedV128Lane(0), 10);
75+
assert_equals(reexporterModule.getImportedV128Lane(1), 20);
76+
assert_equals(reexporterModule.getImportedV128Lane(2), 30);
77+
assert_equals(reexporterModule.getImportedV128Lane(3), 40);
78+
}, "v128 global mutations should work correctly between WebAssembly modules");
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// META: global=window,dedicatedworker,jsshell,shadowrealm
2+
3+
promise_test(async () => {
4+
const wasmNamespace = await import("./resources/mutable-global-export.wasm");
5+
const instance = WebAssembly.namespaceInstance(wasmNamespace);
6+
7+
assert_true(instance instanceof WebAssembly.Instance);
8+
9+
wasmNamespace.setGlobal(999);
10+
assert_equals(instance.exports.getGlobal(), 999);
11+
12+
instance.exports.setGlobal(888);
13+
assert_equals(wasmNamespace.getGlobal(), 888);
14+
}, "WebAssembly.namespaceInstance() should return the underlying instance with shared state");
15+
16+
promise_test(async () => {
17+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance({}));
18+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(null));
19+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(undefined));
20+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(42));
21+
assert_throws_js(TypeError, () =>
22+
WebAssembly.namespaceInstance("not a namespace")
23+
);
24+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance([]));
25+
assert_throws_js(TypeError, () =>
26+
WebAssembly.namespaceInstance(function () {})
27+
);
28+
29+
const jsModule = await import("./resources/globals.js");
30+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(jsModule));
31+
}, "WebAssembly.namespaceInstance() should throw TypeError for non-WebAssembly namespaces");
32+
33+
promise_test(async () => {
34+
const exportsModule = await import("./resources/exports.wasm");
35+
const globalsModule = await import("./resources/globals.wasm");
36+
37+
const exportsInstance = WebAssembly.namespaceInstance(exportsModule);
38+
const globalsInstance = WebAssembly.namespaceInstance(globalsModule);
39+
40+
assert_not_equals(exportsInstance, globalsInstance);
41+
assert_true(exportsInstance.exports.func instanceof Function);
42+
assert_true(globalsInstance.exports.getLocalMutI32 instanceof Function);
43+
44+
globalsModule.setLocalMutI32(12345);
45+
assert_equals(globalsInstance.exports.getLocalMutI32(), 12345);
46+
47+
globalsInstance.exports.setLocalMutI32(54321);
48+
assert_equals(globalsModule.getLocalMutI32(), 54321);
49+
50+
const exportsInstance2 = WebAssembly.namespaceInstance(exportsModule);
51+
assert_equals(exportsInstance, exportsInstance2);
52+
}, "WebAssembly.namespaceInstance() should work correctly with multiple modules");

0 commit comments

Comments
 (0)