| /** |
| * `t` should be a function that takes at least three arguments: |
| * |
| * - the name of the test; |
| * - the expected error (to be passed to `assert_throws_js`); |
| * - a function that takes a `WasmModuleBuilder` and initializes it; |
| * - (optionally) an options object. |
| * |
| * The function is expected to create a test that checks if instantiating a |
| * module with the result of the `WasmModuleBuilder` and the options object |
| * (if any) yields the correct error. |
| */ |
| function test_bad_imports(t) { |
| function value_type(type) { |
| switch (type) { |
| case "i32": return kWasmI32; |
| case "i64": return kWasmI64; |
| case "f32": return kWasmF32; |
| case "f64": return kWasmF64; |
| default: throw new TypeError(`Unexpected type ${type}`); |
| } |
| } |
| |
| for (const value of [null, true, "", Symbol(), 1, 0.1, NaN]) { |
| t(`Non-object imports argument: ${format_value(value)}`, |
| TypeError, |
| builder => {}, |
| value); |
| } |
| |
| for (const value of [undefined, null, true, "", Symbol(), 1, 0.1, NaN]) { |
| const imports = { |
| "module": value, |
| }; |
| t(`Non-object module: ${format_value(value)}`, |
| TypeError, |
| builder => { |
| builder.addImport("module", "fn", kSig_v_v); |
| }, |
| imports); |
| } |
| |
| t(`Missing imports argument`, |
| TypeError, |
| builder => { |
| builder.addImport("module", "fn", kSig_v_v); |
| }); |
| |
| for (const [value, name] of [[undefined, "undefined"], [{}, "empty object"], [{ "module\0": null }, "wrong property"]]) { |
| t(`Imports argument with missing property: ${name}`, |
| TypeError, |
| builder => { |
| builder.addImport("module", "fn", kSig_v_v); |
| }, |
| value); |
| } |
| |
| for (const value of [undefined, null, true, "", Symbol(), 1, 0.1, NaN, {}]) { |
| t(`Importing a function with an incorrectly-typed value: ${format_value(value)}`, |
| WebAssembly.LinkError, |
| builder => { |
| builder.addImport("module", "fn", kSig_v_v); |
| }, |
| { |
| "module": { |
| "fn": value, |
| }, |
| }); |
| } |
| |
| const nonGlobals = [ |
| [undefined], |
| [null], |
| [true], |
| [""], |
| [Symbol()], |
| [{}, "plain object"], |
| [WebAssembly.Global, "WebAssembly.Global"], |
| [WebAssembly.Global.prototype, "WebAssembly.Global.prototype"], |
| [Object.create(WebAssembly.Global.prototype), "Object.create(WebAssembly.Global.prototype)"], |
| ]; |
| |
| for (const type of ["i32", "i64", "f32", "f64"]) { |
| const extendedNonGlobals = nonGlobals.concat([ |
| type === "i64" ? [0, "Number"] : [0n, "BigInt"], |
| [new WebAssembly.Global({value: type === "f32" ? "f64" : "f32"}), "WebAssembly.Global object (wrong value type)"], |
| ]); |
| for (const [value, name = format_value(value)] of extendedNonGlobals) { |
| t(`Importing an ${type} global with an incorrectly-typed value: ${name}`, |
| WebAssembly.LinkError, |
| builder => { |
| builder.addImportedGlobal("module", "global", value_type(type)); |
| }, |
| { |
| "module": { |
| "global": value, |
| }, |
| }); |
| } |
| } |
| |
| for (const type of ["i32", "i64", "f32", "f64"]) { |
| const value = type === "i64" ? 0n : 0; |
| t(`Importing an ${type} mutable global with a primitive value`, |
| WebAssembly.LinkError, |
| builder => { |
| builder.addImportedGlobal("module", "global", value_type(type), true); |
| }, |
| { |
| "module": { |
| "global": value, |
| }, |
| }); |
| |
| const global = new WebAssembly.Global({ "value": type }, value); |
| t(`Importing an ${type} mutable global with an immutable Global object`, |
| WebAssembly.LinkError, |
| builder => { |
| builder.addImportedGlobal("module", "global", value_type(type), true); |
| }, |
| { |
| "module": { |
| "global": global, |
| }, |
| }); |
| } |
| |
| const nonMemories = [ |
| [undefined], |
| [null], |
| [true], |
| [""], |
| [Symbol()], |
| [1], |
| [0.1], |
| [NaN], |
| [{}, "plain object"], |
| [WebAssembly.Memory, "WebAssembly.Memory"], |
| [WebAssembly.Memory.prototype, "WebAssembly.Memory.prototype"], |
| [Object.create(WebAssembly.Memory.prototype), "Object.create(WebAssembly.Memory.prototype)"], |
| [new WebAssembly.Memory({"initial": 256}), "WebAssembly.Memory object (too large)"], |
| ]; |
| |
| for (const [value, name = format_value(value)] of nonMemories) { |
| t(`Importing memory with an incorrectly-typed value: ${name}`, |
| WebAssembly.LinkError, |
| builder => { |
| builder.addImportedMemory("module", "memory", 0, 128); |
| }, |
| { |
| "module": { |
| "memory": value, |
| }, |
| }); |
| } |
| |
| const nonTables = [ |
| [undefined], |
| [null], |
| [true], |
| [""], |
| [Symbol()], |
| [1], |
| [0.1], |
| [NaN], |
| [{}, "plain object"], |
| [WebAssembly.Table, "WebAssembly.Table"], |
| [WebAssembly.Table.prototype, "WebAssembly.Table.prototype"], |
| [Object.create(WebAssembly.Table.prototype), "Object.create(WebAssembly.Table.prototype)"], |
| [new WebAssembly.Table({"element": "anyfunc", "initial": 256}), "WebAssembly.Table object (too large)"], |
| ]; |
| |
| for (const [value, name = format_value(value)] of nonTables) { |
| t(`Importing table with an incorrectly-typed value: ${name}`, |
| WebAssembly.LinkError, |
| builder => { |
| builder.addImportedTable("module", "table", 0, 128); |
| }, |
| { |
| "module": { |
| "table": value, |
| }, |
| }); |
| } |
| } |