summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/wasm/jsapi/module
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/wasm/jsapi/module')
-rw-r--r--testing/web-platform/tests/wasm/jsapi/module/constructor.any.js69
-rw-r--r--testing/web-platform/tests/wasm/jsapi/module/customSections.any.js140
-rw-r--r--testing/web-platform/tests/wasm/jsapi/module/exports.any.js185
-rw-r--r--testing/web-platform/tests/wasm/jsapi/module/imports.any.js185
-rw-r--r--testing/web-platform/tests/wasm/jsapi/module/moduleSource.tentative.any.js41
-rw-r--r--testing/web-platform/tests/wasm/jsapi/module/toString.any.js18
6 files changed, 638 insertions, 0 deletions
diff --git a/testing/web-platform/tests/wasm/jsapi/module/constructor.any.js b/testing/web-platform/tests/wasm/jsapi/module/constructor.any.js
new file mode 100644
index 0000000000..95604aabe4
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/module/constructor.any.js
@@ -0,0 +1,69 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+// META: script=/wasm/jsapi/assertions.js
+
+let emptyModuleBinary;
+setup(() => {
+ emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+});
+
+test(() => {
+ assert_function_name(WebAssembly.Module, "Module", "WebAssembly.Module");
+}, "name");
+
+test(() => {
+ assert_function_length(WebAssembly.Module, 1, "WebAssembly.Module");
+}, "length");
+
+test(() => {
+ assert_throws_js(TypeError, () => new WebAssembly.Module());
+}, "No arguments");
+
+test(() => {
+ assert_throws_js(TypeError, () => WebAssembly.Module(emptyModuleBinary));
+}, "Calling");
+
+test(() => {
+ const invalidArguments = [
+ undefined,
+ null,
+ true,
+ "test",
+ Symbol(),
+ 7,
+ NaN,
+ {},
+ ArrayBuffer,
+ ArrayBuffer.prototype,
+ Array.from(emptyModuleBinary),
+ ];
+ for (const argument of invalidArguments) {
+ assert_throws_js(TypeError, () => new WebAssembly.Module(argument),
+ `new Module(${format_value(argument)})`);
+ }
+}, "Invalid arguments");
+
+test(() => {
+ const buffer = new Uint8Array();
+ assert_throws_js(WebAssembly.CompileError, () => new WebAssembly.Module(buffer));
+}, "Empty buffer");
+
+test(() => {
+ const buffer = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0]));
+ assert_throws_js(WebAssembly.CompileError, () => new WebAssembly.Module(buffer));
+}, "Invalid code");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype);
+}, "Prototype");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_true(Object.isExtensible(module));
+}, "Extensibility");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary, {});
+ assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype);
+}, "Stray argument");
diff --git a/testing/web-platform/tests/wasm/jsapi/module/customSections.any.js b/testing/web-platform/tests/wasm/jsapi/module/customSections.any.js
new file mode 100644
index 0000000000..96958316e0
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/module/customSections.any.js
@@ -0,0 +1,140 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+function assert_ArrayBuffer(buffer, expected) {
+ assert_equals(Object.getPrototypeOf(buffer), ArrayBuffer.prototype, "Prototype");
+ assert_true(Object.isExtensible(buffer), "isExtensible");
+ assert_array_equals(new Uint8Array(buffer), expected);
+}
+
+function assert_sections(sections, expected) {
+ assert_true(Array.isArray(sections), "Should be array");
+ assert_equals(Object.getPrototypeOf(sections), Array.prototype, "Prototype");
+ assert_true(Object.isExtensible(sections), "isExtensible");
+
+ assert_equals(sections.length, expected.length);
+ for (let i = 0; i < expected.length; ++i) {
+ assert_ArrayBuffer(sections[i], expected[i]);
+ }
+}
+
+let emptyModuleBinary;
+setup(() => {
+ emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+});
+
+test(() => {
+ assert_throws_js(TypeError, () => WebAssembly.Module.customSections());
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_throws_js(TypeError, () => WebAssembly.Module.customSections(module));
+}, "Missing arguments");
+
+test(() => {
+ const invalidArguments = [
+ undefined,
+ null,
+ true,
+ "",
+ Symbol(),
+ 1,
+ {},
+ WebAssembly.Module,
+ WebAssembly.Module.prototype,
+ ];
+ for (const argument of invalidArguments) {
+ assert_throws_js(TypeError, () => WebAssembly.Module.customSections(argument, ""),
+ `customSections(${format_value(argument)})`);
+ }
+}, "Non-Module arguments");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const fn = WebAssembly.Module.customSections;
+ const thisValues = [
+ undefined,
+ null,
+ true,
+ "",
+ Symbol(),
+ 1,
+ {},
+ WebAssembly.Module,
+ WebAssembly.Module.prototype,
+ ];
+ for (const thisValue of thisValues) {
+ assert_sections(fn.call(thisValue, module, ""), []);
+ }
+}, "Branding");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_sections(WebAssembly.Module.customSections(module, ""), []);
+}, "Empty module");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_not_equals(WebAssembly.Module.customSections(module, ""),
+ WebAssembly.Module.customSections(module, ""));
+}, "Empty module: array caching");
+
+test(() => {
+ const bytes1 = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
+ const bytes2 = [74, 83, 65, 80, 73];
+
+ const builder = new WasmModuleBuilder();
+ builder.addCustomSection("name", bytes1);
+ builder.addCustomSection("name", bytes2);
+ builder.addCustomSection("foo", bytes1);
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+
+ assert_sections(WebAssembly.Module.customSections(module, "name"), [
+ bytes1,
+ bytes2,
+ ])
+
+ assert_sections(WebAssembly.Module.customSections(module, "foo"), [
+ bytes1,
+ ])
+
+ assert_sections(WebAssembly.Module.customSections(module, ""), [])
+ assert_sections(WebAssembly.Module.customSections(module, "\0"), [])
+ assert_sections(WebAssembly.Module.customSections(module, "name\0"), [])
+ assert_sections(WebAssembly.Module.customSections(module, "foo\0"), [])
+}, "Custom sections");
+
+test(() => {
+ const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
+ const name = "yee\uD801\uDC37eey"
+
+ const builder = new WasmModuleBuilder();
+ builder.addCustomSection(name, bytes);
+ const buffer = builder.toBuffer();
+ const module = new WebAssembly.Module(buffer);
+
+ assert_sections(WebAssembly.Module.customSections(module, name), [
+ bytes,
+ ]);
+ assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFDeey"), []);
+ assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFD\uFFFDeey"), []);
+}, "Custom sections with surrogate pairs");
+
+test(() => {
+ const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
+
+ const builder = new WasmModuleBuilder();
+ builder.addCustomSection("na\uFFFDme", bytes);
+ const buffer = builder.toBuffer();
+ const module = new WebAssembly.Module(buffer);
+
+ assert_sections(WebAssembly.Module.customSections(module, "name"), []);
+ assert_sections(WebAssembly.Module.customSections(module, "na\uFFFDme"), [
+ bytes,
+ ]);
+ assert_sections(WebAssembly.Module.customSections(module, "na\uDC01me"), []);
+}, "Custom sections with U+FFFD");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_sections(WebAssembly.Module.customSections(module, "", {}), []);
+}, "Stray argument");
diff --git a/testing/web-platform/tests/wasm/jsapi/module/exports.any.js b/testing/web-platform/tests/wasm/jsapi/module/exports.any.js
new file mode 100644
index 0000000000..0c32e984a2
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/module/exports.any.js
@@ -0,0 +1,185 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+let emptyModuleBinary;
+setup(() => {
+ emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+});
+
+function assert_ModuleExportDescriptor(export_, expected) {
+ assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype");
+ assert_true(Object.isExtensible(export_), "isExtensible");
+
+ const name = Object.getOwnPropertyDescriptor(export_, "name");
+ assert_true(name.writable, "name: writable");
+ assert_true(name.enumerable, "name: enumerable");
+ assert_true(name.configurable, "name: configurable");
+ assert_equals(name.value, expected.name);
+
+ const kind = Object.getOwnPropertyDescriptor(export_, "kind");
+ assert_true(kind.writable, "kind: writable");
+ assert_true(kind.enumerable, "kind: enumerable");
+ assert_true(kind.configurable, "kind: configurable");
+ assert_equals(kind.value, expected.kind);
+}
+
+function assert_exports(exports, expected) {
+ assert_true(Array.isArray(exports), "Should be array");
+ assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
+ assert_true(Object.isExtensible(exports), "isExtensible");
+
+ assert_equals(exports.length, expected.length);
+ for (let i = 0; i < expected.length; ++i) {
+ assert_ModuleExportDescriptor(exports[i], expected[i]);
+ }
+}
+
+test(() => {
+ assert_throws_js(TypeError, () => WebAssembly.Module.exports());
+}, "Missing arguments");
+
+test(() => {
+ const invalidArguments = [
+ undefined,
+ null,
+ true,
+ "",
+ Symbol(),
+ 1,
+ {},
+ WebAssembly.Module,
+ WebAssembly.Module.prototype,
+ ];
+ for (const argument of invalidArguments) {
+ assert_throws_js(TypeError, () => WebAssembly.Module.exports(argument),
+ `exports(${format_value(argument)})`);
+ }
+}, "Non-Module arguments");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const fn = WebAssembly.Module.exports;
+ const thisValues = [
+ undefined,
+ null,
+ true,
+ "",
+ Symbol(),
+ 1,
+ {},
+ WebAssembly.Module,
+ WebAssembly.Module.prototype,
+ ];
+ for (const thisValue of thisValues) {
+ assert_array_equals(fn.call(thisValue, module), []);
+ }
+}, "Branding");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const exports = WebAssembly.Module.exports(module);
+ assert_true(Array.isArray(exports));
+}, "Return type");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const exports = WebAssembly.Module.exports(module);
+ assert_exports(exports, []);
+}, "Empty module");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_not_equals(WebAssembly.Module.exports(module), WebAssembly.Module.exports(module));
+}, "Empty module: array caching");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder
+ .addFunction("fn", kSig_v_v)
+ .addBody([])
+ .exportFunc();
+ builder
+ .addFunction("fn2", kSig_v_v)
+ .addBody([])
+ .exportFunc();
+
+ builder.setTableBounds(1);
+ builder.addExportOfKind("table", kExternalTable, 0);
+
+ builder.addGlobal(kWasmI32, true)
+ .exportAs("global")
+ .init = wasmI32Const(7);
+ builder.addGlobal(kWasmF64, true)
+ .exportAs("global2")
+ .init = wasmF64Const(1.2);
+
+ builder.addMemory(0, 256, true);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const exports = WebAssembly.Module.exports(module);
+ const expected = [
+ { "kind": "function", "name": "fn" },
+ { "kind": "function", "name": "fn2" },
+ { "kind": "table", "name": "table" },
+ { "kind": "global", "name": "global" },
+ { "kind": "global", "name": "global2" },
+ { "kind": "memory", "name": "memory" },
+ ];
+ assert_exports(exports, expected);
+}, "exports");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder
+ .addFunction("", kSig_v_v)
+ .addBody([])
+ .exportFunc();
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const exports = WebAssembly.Module.exports(module);
+ const expected = [
+ { "kind": "function", "name": "" },
+ ];
+ assert_exports(exports, expected);
+}, "exports with empty name: function");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder.setTableBounds(1);
+ builder.addExportOfKind("", kExternalTable, 0);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const exports = WebAssembly.Module.exports(module);
+ const expected = [
+ { "kind": "table", "name": "" },
+ ];
+ assert_exports(exports, expected);
+}, "exports with empty name: table");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder.addGlobal(kWasmI32, true)
+ .exportAs("")
+ .init = wasmI32Const(7);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const exports = WebAssembly.Module.exports(module);
+ const expected = [
+ { "kind": "global", "name": "" },
+ ];
+ assert_exports(exports, expected);
+}, "exports with empty name: global");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const exports = WebAssembly.Module.exports(module, {});
+ assert_exports(exports, []);
+}, "Stray argument");
diff --git a/testing/web-platform/tests/wasm/jsapi/module/imports.any.js b/testing/web-platform/tests/wasm/jsapi/module/imports.any.js
new file mode 100644
index 0000000000..2ab1725359
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/module/imports.any.js
@@ -0,0 +1,185 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+function assert_ModuleImportDescriptor(import_, expected) {
+ assert_equals(Object.getPrototypeOf(import_), Object.prototype, "Prototype");
+ assert_true(Object.isExtensible(import_), "isExtensible");
+
+ const module = Object.getOwnPropertyDescriptor(import_, "module");
+ assert_true(module.writable, "module: writable");
+ assert_true(module.enumerable, "module: enumerable");
+ assert_true(module.configurable, "module: configurable");
+ assert_equals(module.value, expected.module);
+
+ const name = Object.getOwnPropertyDescriptor(import_, "name");
+ assert_true(name.writable, "name: writable");
+ assert_true(name.enumerable, "name: enumerable");
+ assert_true(name.configurable, "name: configurable");
+ assert_equals(name.value, expected.name);
+
+ const kind = Object.getOwnPropertyDescriptor(import_, "kind");
+ assert_true(kind.writable, "kind: writable");
+ assert_true(kind.enumerable, "kind: enumerable");
+ assert_true(kind.configurable, "kind: configurable");
+ assert_equals(kind.value, expected.kind);
+}
+
+function assert_imports(imports, expected) {
+ assert_true(Array.isArray(imports), "Should be array");
+ assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype");
+ assert_true(Object.isExtensible(imports), "isExtensible");
+
+ assert_equals(imports.length, expected.length);
+ for (let i = 0; i < expected.length; ++i) {
+ assert_ModuleImportDescriptor(imports[i], expected[i]);
+ }
+}
+
+let emptyModuleBinary;
+setup(() => {
+ emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+});
+
+test(() => {
+ assert_throws_js(TypeError, () => WebAssembly.Module.imports());
+}, "Missing arguments");
+
+test(() => {
+ const invalidArguments = [
+ undefined,
+ null,
+ true,
+ "",
+ Symbol(),
+ 1,
+ {},
+ WebAssembly.Module,
+ WebAssembly.Module.prototype,
+ ];
+ for (const argument of invalidArguments) {
+ assert_throws_js(TypeError, () => WebAssembly.Module.imports(argument),
+ `imports(${format_value(argument)})`);
+ }
+}, "Non-Module arguments");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const fn = WebAssembly.Module.imports;
+ const thisValues = [
+ undefined,
+ null,
+ true,
+ "",
+ Symbol(),
+ 1,
+ {},
+ WebAssembly.Module,
+ WebAssembly.Module.prototype,
+ ];
+ for (const thisValue of thisValues) {
+ assert_array_equals(fn.call(thisValue, module), []);
+ }
+}, "Branding");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const imports = WebAssembly.Module.imports(module);
+ assert_true(Array.isArray(imports));
+}, "Return type");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const imports = WebAssembly.Module.imports(module);
+ assert_imports(imports, []);
+}, "Empty module");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_not_equals(WebAssembly.Module.imports(module), WebAssembly.Module.imports(module));
+}, "Empty module: array caching");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder.addImport("module", "fn", kSig_v_v);
+ builder.addImportedGlobal("module", "global", kWasmI32);
+ builder.addImportedMemory("module", "memory", 0, 128);
+ builder.addImportedTable("module", "table", 0, 128);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const imports = WebAssembly.Module.imports(module);
+ const expected = [
+ { "module": "module", "kind": "function", "name": "fn" },
+ { "module": "module", "kind": "global", "name": "global" },
+ { "module": "module", "kind": "memory", "name": "memory" },
+ { "module": "module", "kind": "table", "name": "table" },
+ ];
+ assert_imports(imports, expected);
+}, "imports");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder.addImport("", "fn", kSig_v_v);
+ builder.addImportedGlobal("", "global", kWasmI32);
+ builder.addImportedMemory("", "memory", 0, 128);
+ builder.addImportedTable("", "table", 0, 128);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const imports = WebAssembly.Module.imports(module);
+ const expected = [
+ { "module": "", "kind": "function", "name": "fn" },
+ { "module": "", "kind": "global", "name": "global" },
+ { "module": "", "kind": "memory", "name": "memory" },
+ { "module": "", "kind": "table", "name": "table" },
+ ];
+ assert_imports(imports, expected);
+}, "imports with empty module name");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder.addImport("a", "", kSig_v_v);
+ builder.addImportedGlobal("b", "", kWasmI32);
+ builder.addImportedMemory("c", "", 0, 128);
+ builder.addImportedTable("d", "", 0, 128);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const imports = WebAssembly.Module.imports(module);
+ const expected = [
+ { "module": "a", "kind": "function", "name": "" },
+ { "module": "b", "kind": "global", "name": "" },
+ { "module": "c", "kind": "memory", "name": "" },
+ { "module": "d", "kind": "table", "name": "" },
+ ];
+ assert_imports(imports, expected);
+}, "imports with empty names");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder.addImport("", "", kSig_v_v);
+ builder.addImportedGlobal("", "", kWasmI32);
+ builder.addImportedMemory("", "", 0, 128);
+ builder.addImportedTable("", "", 0, 128);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+ const imports = WebAssembly.Module.imports(module);
+ const expected = [
+ { "module": "", "kind": "function", "name": "" },
+ { "module": "", "kind": "global", "name": "" },
+ { "module": "", "kind": "memory", "name": "" },
+ { "module": "", "kind": "table", "name": "" },
+ ];
+ assert_imports(imports, expected);
+}, "imports with empty module names and names");
+
+test(() => {
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ const imports = WebAssembly.Module.imports(module, {});
+ assert_imports(imports, []);
+}, "Stray argument");
diff --git a/testing/web-platform/tests/wasm/jsapi/module/moduleSource.tentative.any.js b/testing/web-platform/tests/wasm/jsapi/module/moduleSource.tentative.any.js
new file mode 100644
index 0000000000..a3d09d55d6
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/module/moduleSource.tentative.any.js
@@ -0,0 +1,41 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+// META: script=/wasm/jsapi/assertions.js
+
+let emptyModuleBinary;
+setup(() => {
+ emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+});
+
+test(() => {
+ assert_equals(typeof AbstractModuleSource, "undefined");
+ const AbstractModuleSource = Object.getPrototypeOf(WebAssembly.Module);
+ assert_equals(AbstractModuleSource.name, "AbstractModuleSource");
+ assert_not_equals(AbstractModuleSource, Function);
+}, "AbstractModuleSource intrinsic");
+
+test(() => {
+ const AbstractModuleSourceProto = Object.getPrototypeOf(WebAssembly.Module.prototype);
+ assert_not_equals(AbstractModuleSourceProto, Object);
+ const AbstractModuleSource = Object.getPrototypeOf(WebAssembly.Module);
+ assert_equals(AbstractModuleSource.prototype, AbstractModuleSourceProto);
+}, "AbstractModuleSourceProto intrinsic");
+
+test(() => {
+ const builder = new WasmModuleBuilder();
+
+ builder
+ .addFunction("fn", kSig_v_v)
+ .addBody([])
+ .exportFunc();
+ builder.addMemory(0, 256, true);
+
+ const buffer = builder.toBuffer()
+ const module = new WebAssembly.Module(buffer);
+
+ const AbstractModuleSource = Object.getPrototypeOf(WebAssembly.Module);
+ const toStringTag = Object.getOwnPropertyDescriptor(AbstractModuleSource.prototype, Symbol.toStringTag).get;
+
+ assert_equals(toStringTag.call(module), "WebAssembly.Module");
+ assert_throws_js(TypeError, () => toStringTag.call({}));
+}, "AbstractModuleSourceProto toStringTag brand check"); \ No newline at end of file
diff --git a/testing/web-platform/tests/wasm/jsapi/module/toString.any.js b/testing/web-platform/tests/wasm/jsapi/module/toString.any.js
new file mode 100644
index 0000000000..10c707979d
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/module/toString.any.js
@@ -0,0 +1,18 @@
+// META: global=window,dedicatedworker,jsshell,shadowrealm
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+test(() => {
+ const emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+ const module = new WebAssembly.Module(emptyModuleBinary);
+ assert_class_string(module, "WebAssembly.Module");
+}, "Object.prototype.toString on an Module");
+
+test(() => {
+ assert_own_property(WebAssembly.Module.prototype, Symbol.toStringTag);
+
+ const propDesc = Object.getOwnPropertyDescriptor(WebAssembly.Module.prototype, Symbol.toStringTag);
+ assert_equals(propDesc.value, "WebAssembly.Module", "value");
+ assert_equals(propDesc.configurable, true, "configurable");
+ assert_equals(propDesc.enumerable, false, "enumerable");
+ assert_equals(propDesc.writable, false, "writable");
+}, "@@toStringTag exists on the prototype with the appropriate descriptor");