Skip to content

Commit 919e6b1

Browse files
authored
[wasm] Upstream ESM Integration jsapi tests (#53718)
1 parent 3bc11de commit 919e6b1

33 files changed

+565
-0
lines changed
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: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// META: global=window,dedicatedworker,jsshell,shadowrealm
2+
3+
promise_test(async () => {
4+
const exporterModule = await import("./resources/mutable-global-export.wasm");
5+
const reexporterModule = await import(
6+
"./resources/mutable-global-reexport.wasm"
7+
);
8+
9+
assert_equals(exporterModule.mutableValue, 100);
10+
assert_equals(reexporterModule.reexportedMutableValue, 100);
11+
}, "WebAssembly modules should export shared mutable globals with correct initial values");
12+
13+
promise_test(async () => {
14+
const exporterModule = await import("./resources/mutable-global-export.wasm");
15+
const reexporterModule = await import(
16+
"./resources/mutable-global-reexport.wasm"
17+
);
18+
19+
exporterModule.setGlobal(500);
20+
21+
assert_equals(exporterModule.getGlobal(), 500, "exporter should see 500");
22+
assert_equals(reexporterModule.getImportedGlobal(), 500);
23+
24+
reexporterModule.setImportedGlobal(600);
25+
26+
assert_equals(exporterModule.getGlobal(), 600);
27+
assert_equals(reexporterModule.getImportedGlobal(), 600);
28+
29+
exporterModule.setGlobal(700);
30+
31+
assert_equals(exporterModule.getGlobal(), 700);
32+
assert_equals(reexporterModule.getImportedGlobal(), 700);
33+
}, "Wasm-to-Wasm mutable global sharing is live");
34+
35+
promise_test(async () => {
36+
const module1 = await import("./resources/mutable-global-export.wasm");
37+
const module2 = await import("./resources/mutable-global-export.wasm");
38+
39+
assert_equals(module1, module2);
40+
41+
module1.setGlobal(800);
42+
assert_equals(module1.getGlobal(), 800, "module1 should see its own change");
43+
assert_equals(module2.getGlobal(), 800);
44+
}, "Multiple JavaScript imports return the same WebAssembly module instance");
45+
46+
promise_test(async () => {
47+
const exporterModule = await import("./resources/mutable-global-export.wasm");
48+
const reexporterModule = await import(
49+
"./resources/mutable-global-reexport.wasm"
50+
);
51+
52+
assert_equals(exporterModule.getV128Lane(0), 1);
53+
assert_equals(exporterModule.getV128Lane(1), 2);
54+
assert_equals(exporterModule.getV128Lane(2), 3);
55+
assert_equals(exporterModule.getV128Lane(3), 4);
56+
57+
assert_equals(reexporterModule.getImportedV128Lane(0), 1);
58+
assert_equals(reexporterModule.getImportedV128Lane(1), 2);
59+
assert_equals(reexporterModule.getImportedV128Lane(2), 3);
60+
assert_equals(reexporterModule.getImportedV128Lane(3), 4);
61+
}, "v128 globals should work correctly in WebAssembly-to-WebAssembly imports");
62+
63+
promise_test(async () => {
64+
const exporterModule = await import("./resources/mutable-global-export.wasm");
65+
const reexporterModule = await import(
66+
"./resources/mutable-global-reexport.wasm"
67+
);
68+
69+
exporterModule.setV128Global(10, 20, 30, 40);
70+
71+
assert_equals(exporterModule.getV128Lane(0), 10);
72+
assert_equals(exporterModule.getV128Lane(1), 20);
73+
assert_equals(exporterModule.getV128Lane(2), 30);
74+
assert_equals(exporterModule.getV128Lane(3), 40);
75+
76+
assert_equals(reexporterModule.getImportedV128Lane(0), 10);
77+
assert_equals(reexporterModule.getImportedV128Lane(1), 20);
78+
assert_equals(reexporterModule.getImportedV128Lane(2), 30);
79+
assert_equals(reexporterModule.getImportedV128Lane(3), 40);
80+
}, "v128 global mutations should work correctly between WebAssembly modules");
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
const wasmNamespace2 = await import("./resources/mutable-global-export.wasm");
8+
const instance2 = WebAssembly.namespaceInstance(wasmNamespace2);
9+
assert_equals(instance, instance2);
10+
11+
assert_true(instance instanceof WebAssembly.Instance);
12+
13+
wasmNamespace.setGlobal(999);
14+
assert_equals(instance.exports.getGlobal(), 999);
15+
16+
instance.exports.setGlobal(888);
17+
assert_equals(wasmNamespace.getGlobal(), 888);
18+
}, "WebAssembly.namespaceInstance() should return the underlying instance with shared state");
19+
20+
promise_test(async () => {
21+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance({}));
22+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(null));
23+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(undefined));
24+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(42));
25+
assert_throws_js(TypeError, () =>
26+
WebAssembly.namespaceInstance("not a namespace")
27+
);
28+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance([]));
29+
assert_throws_js(TypeError, () =>
30+
WebAssembly.namespaceInstance(function () {})
31+
);
32+
33+
const jsModule = await import("./resources/globals.js");
34+
assert_throws_js(TypeError, () => WebAssembly.namespaceInstance(jsModule));
35+
}, "WebAssembly.namespaceInstance() should throw TypeError for non-WebAssembly namespaces");
36+
37+
promise_test(async () => {
38+
const exportsModule = await import("./resources/exports.wasm");
39+
const globalsModule = await import("./resources/globals.wasm");
40+
41+
const exportsInstance = WebAssembly.namespaceInstance(exportsModule);
42+
const globalsInstance = WebAssembly.namespaceInstance(globalsModule);
43+
44+
assert_not_equals(exportsInstance, globalsInstance);
45+
assert_true(exportsInstance.exports.func instanceof Function);
46+
assert_true(globalsInstance.exports.getLocalMutI32 instanceof Function);
47+
48+
globalsModule.setLocalMutI32(12345);
49+
assert_equals(globalsInstance.exports.getLocalMutI32(), 12345);
50+
51+
globalsInstance.exports.setLocalMutI32(54321);
52+
assert_equals(globalsModule.getLocalMutI32(), 54321);
53+
54+
const exportsInstance2 = WebAssembly.namespaceInstance(exportsModule);
55+
assert_equals(exportsInstance, exportsInstance2);
56+
}, "WebAssembly.namespaceInstance() should work correctly with multiple modules");
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Test that wasm: and wasm-js: reserved cases should cause WebAssembly.LinkError
2+
3+
promise_test(async (t) => {
4+
await promise_rejects_js(
5+
t,
6+
WebAssembly.LinkError,
7+
import("./resources/invalid-import-name.wasm")
8+
);
9+
}, "wasm: reserved import names should cause WebAssembly.LinkError");
10+
11+
promise_test(async (t) => {
12+
await promise_rejects_js(
13+
t,
14+
WebAssembly.LinkError,
15+
import("./resources/invalid-import-name-wasm-js.wasm")
16+
);
17+
}, "wasm-js: reserved import names should cause WebAssembly.LinkError");
18+
19+
promise_test(async (t) => {
20+
await promise_rejects_js(
21+
t,
22+
WebAssembly.LinkError,
23+
import("./resources/invalid-export-name.wasm")
24+
);
25+
}, "wasm: reserved export names should cause WebAssembly.LinkError");
26+
27+
promise_test(async (t) => {
28+
await promise_rejects_js(
29+
t,
30+
WebAssembly.LinkError,
31+
import("./resources/invalid-export-name-wasm-js.wasm")
32+
);
33+
}, "wasm-js: reserved export names should cause WebAssembly.LinkError");
34+
35+
promise_test(async (t) => {
36+
await promise_rejects_js(
37+
t,
38+
WebAssembly.LinkError,
39+
import("./resources/invalid-import-module.wasm")
40+
);
41+
}, "wasm-js: reserved module names should cause WebAssembly.LinkError");
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// META: global=window,dedicatedworker,jsshell,shadowrealm
2+
3+
promise_test(async (t) => {
4+
await promise_rejects_js(
5+
t,
6+
SyntaxError,
7+
import("./resources/resolve-export.js")
8+
);
9+
}, "ResolveExport on invalid re-export from WebAssembly");
529 Bytes
Binary file not shown.
226 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)