1/** 2 * `t` should be a function that takes at least three arguments: 3 * 4 * - the name of the test; 5 * - the expected error (to be passed to `assert_throws_js`); 6 * - a function that takes a `WasmModuleBuilder` and initializes it; 7 * - (optionally) an options object. 8 * 9 * The function is expected to create a test that checks if instantiating a 10 * module with the result of the `WasmModuleBuilder` and the options object 11 * (if any) yields the correct error. 12 */ 13function test_bad_imports(t) { 14 function value_type(type) { 15 switch (type) { 16 case "i32": return kWasmI32; 17 case "i64": return kWasmI64; 18 case "f32": return kWasmF32; 19 case "f64": return kWasmF64; 20 default: throw new TypeError(`Unexpected type ${type}`); 21 } 22 } 23 24 for (const value of [null, true, "", Symbol(), 1, 0.1, NaN]) { 25 t(`Non-object imports argument: ${format_value(value)}`, 26 TypeError, 27 builder => {}, 28 value); 29 } 30 31 for (const value of [undefined, null, true, "", Symbol(), 1, 0.1, NaN]) { 32 const imports = { 33 "module": value, 34 }; 35 t(`Non-object module: ${format_value(value)}`, 36 TypeError, 37 builder => { 38 builder.addImport("module", "fn", kSig_v_v); 39 }, 40 imports); 41 } 42 43 t(`Missing imports argument`, 44 TypeError, 45 builder => { 46 builder.addImport("module", "fn", kSig_v_v); 47 }); 48 49 for (const [value, name] of [[undefined, "undefined"], [{}, "empty object"], [{ "module\0": null }, "wrong property"]]) { 50 t(`Imports argument with missing property: ${name}`, 51 TypeError, 52 builder => { 53 builder.addImport("module", "fn", kSig_v_v); 54 }, 55 value); 56 } 57 58 for (const value of [undefined, null, true, "", Symbol(), 1, 0.1, NaN, {}]) { 59 t(`Importing a function with an incorrectly-typed value: ${format_value(value)}`, 60 WebAssembly.LinkError, 61 builder => { 62 builder.addImport("module", "fn", kSig_v_v); 63 }, 64 { 65 "module": { 66 "fn": value, 67 }, 68 }); 69 } 70 71 const nonGlobals = [ 72 [undefined], 73 [null], 74 [true], 75 [""], 76 [Symbol()], 77 [{}, "plain object"], 78 [WebAssembly.Global, "WebAssembly.Global"], 79 [WebAssembly.Global.prototype, "WebAssembly.Global.prototype"], 80 [Object.create(WebAssembly.Global.prototype), "Object.create(WebAssembly.Global.prototype)"], 81 ]; 82 83 for (const type of ["i32", "i64", "f32", "f64"]) { 84 const extendedNonGlobals = nonGlobals.concat([ 85 type === "i64" ? [0, "Number"] : [0n, "BigInt"], 86 [new WebAssembly.Global({value: type === "f32" ? "f64" : "f32"}), "WebAssembly.Global object (wrong value type)"], 87 ]); 88 for (const [value, name = format_value(value)] of extendedNonGlobals) { 89 t(`Importing an ${type} global with an incorrectly-typed value: ${name}`, 90 WebAssembly.LinkError, 91 builder => { 92 builder.addImportedGlobal("module", "global", value_type(type)); 93 }, 94 { 95 "module": { 96 "global": value, 97 }, 98 }); 99 } 100 } 101 102 for (const type of ["i32", "i64", "f32", "f64"]) { 103 const value = type === "i64" ? 0n : 0; 104 t(`Importing an ${type} mutable global with a primitive value`, 105 WebAssembly.LinkError, 106 builder => { 107 builder.addImportedGlobal("module", "global", value_type(type), true); 108 }, 109 { 110 "module": { 111 "global": value, 112 }, 113 }); 114 115 const global = new WebAssembly.Global({ "value": type }, value); 116 t(`Importing an ${type} mutable global with an immutable Global object`, 117 WebAssembly.LinkError, 118 builder => { 119 builder.addImportedGlobal("module", "global", value_type(type), true); 120 }, 121 { 122 "module": { 123 "global": global, 124 }, 125 }); 126 } 127 128 const nonMemories = [ 129 [undefined], 130 [null], 131 [true], 132 [""], 133 [Symbol()], 134 [1], 135 [0.1], 136 [NaN], 137 [{}, "plain object"], 138 [WebAssembly.Memory, "WebAssembly.Memory"], 139 [WebAssembly.Memory.prototype, "WebAssembly.Memory.prototype"], 140 [Object.create(WebAssembly.Memory.prototype), "Object.create(WebAssembly.Memory.prototype)"], 141 [new WebAssembly.Memory({"initial": 256}), "WebAssembly.Memory object (too large)"], 142 ]; 143 144 for (const [value, name = format_value(value)] of nonMemories) { 145 t(`Importing memory with an incorrectly-typed value: ${name}`, 146 WebAssembly.LinkError, 147 builder => { 148 builder.addImportedMemory("module", "memory", 0, 128); 149 }, 150 { 151 "module": { 152 "memory": value, 153 }, 154 }); 155 } 156 157 const nonTables = [ 158 [undefined], 159 [null], 160 [true], 161 [""], 162 [Symbol()], 163 [1], 164 [0.1], 165 [NaN], 166 [{}, "plain object"], 167 [WebAssembly.Table, "WebAssembly.Table"], 168 [WebAssembly.Table.prototype, "WebAssembly.Table.prototype"], 169 [Object.create(WebAssembly.Table.prototype), "Object.create(WebAssembly.Table.prototype)"], 170 [new WebAssembly.Table({"element": "anyfunc", "initial": 256}), "WebAssembly.Table object (too large)"], 171 ]; 172 173 for (const [value, name = format_value(value)] of nonTables) { 174 t(`Importing table with an incorrectly-typed value: ${name}`, 175 WebAssembly.LinkError, 176 builder => { 177 builder.addImportedTable("module", "table", 0, 128); 178 }, 179 { 180 "module": { 181 "table": value, 182 }, 183 }); 184 } 185} 186