1// META: global=window,dedicatedworker,jsshell 2// META: script=/wasm/jsapi/wasm-module-builder.js 3// META: script=/wasm/jsapi/assertions.js 4// META: script=/wasm/jsapi/table/assertions.js 5 6test(() => { 7 assert_function_name(WebAssembly.Table, "Table", "WebAssembly.Table"); 8}, "name"); 9 10test(() => { 11 assert_function_length(WebAssembly.Table, 1, "WebAssembly.Table"); 12}, "length"); 13 14test(() => { 15 assert_throws_js(TypeError, () => new WebAssembly.Table()); 16}, "No arguments"); 17 18test(() => { 19 const argument = { "element": "anyfunc", "initial": 0 }; 20 assert_throws_js(TypeError, () => WebAssembly.Table(argument)); 21}, "Calling"); 22 23test(() => { 24 assert_throws_js(TypeError, () => new WebAssembly.Table({})); 25}, "Empty descriptor"); 26 27test(() => { 28 const invalidArguments = [ 29 undefined, 30 null, 31 false, 32 true, 33 "", 34 "test", 35 Symbol(), 36 1, 37 NaN, 38 {}, 39 ]; 40 for (const invalidArgument of invalidArguments) { 41 assert_throws_js(TypeError, 42 () => new WebAssembly.Table(invalidArgument), 43 `new Table(${format_value(invalidArgument)})`); 44 } 45}, "Invalid descriptor argument"); 46 47test(() => { 48 assert_throws_js(TypeError, () => new WebAssembly.Table({ "element": "anyfunc", "initial": undefined })); 49}, "Undefined initial value in descriptor"); 50 51test(() => { 52 assert_throws_js(TypeError, () => new WebAssembly.Table({ "element": undefined, "initial": 0 })); 53}, "Undefined element value in descriptor"); 54 55const outOfRangeValues = [ 56 NaN, 57 Infinity, 58 -Infinity, 59 -1, 60 0x100000000, 61 0x1000000000, 62]; 63 64for (const value of outOfRangeValues) { 65 test(() => { 66 assert_throws_js(TypeError, () => new WebAssembly.Table({ "element": "anyfunc", "initial": value })); 67 }, `Out-of-range initial value in descriptor: ${format_value(value)}`); 68 69 test(() => { 70 assert_throws_js(TypeError, () => new WebAssembly.Table({ "element": "anyfunc", "initial": 0, "maximum": value })); 71 }, `Out-of-range maximum value in descriptor: ${format_value(value)}`); 72} 73 74test(() => { 75 assert_throws_js(RangeError, () => new WebAssembly.Table({ "element": "anyfunc", "initial": 10, "maximum": 9 })); 76}, "Initial value exceeds maximum"); 77 78test(() => { 79 const argument = { "element": "anyfunc", "initial": 0 }; 80 const table = new WebAssembly.Table(argument); 81 assert_Table(table, { "length": 0 }); 82}, "Basic (zero)"); 83 84test(() => { 85 const argument = { "element": "anyfunc", "initial": 5 }; 86 const table = new WebAssembly.Table(argument); 87 assert_Table(table, { "length": 5 }); 88}, "Basic (non-zero)"); 89 90test(() => { 91 const argument = { "element": "anyfunc", "initial": 0 }; 92 const table = new WebAssembly.Table(argument, null, {}); 93 assert_Table(table, { "length": 0 }); 94}, "Stray argument"); 95 96test(() => { 97 const proxy = new Proxy({}, { 98 has(o, x) { 99 assert_unreached(`Should not call [[HasProperty]] with ${x}`); 100 }, 101 get(o, x) { 102 switch (x) { 103 case "element": 104 return "anyfunc"; 105 case "initial": 106 case "maximum": 107 return 0; 108 default: 109 return undefined; 110 } 111 }, 112 }); 113 const table = new WebAssembly.Table(proxy); 114 assert_Table(table, { "length": 0 }); 115}, "Proxy descriptor"); 116 117test(() => { 118 const table = new WebAssembly.Table({ 119 "element": { 120 toString() { return "anyfunc"; }, 121 }, 122 "initial": 1, 123 }); 124 assert_Table(table, { "length": 1 }); 125}, "Type conversion for descriptor.element"); 126 127test(() => { 128 const order = []; 129 130 new WebAssembly.Table({ 131 get maximum() { 132 order.push("maximum"); 133 return { 134 valueOf() { 135 order.push("maximum valueOf"); 136 return 1; 137 }, 138 }; 139 }, 140 141 get initial() { 142 order.push("initial"); 143 return { 144 valueOf() { 145 order.push("initial valueOf"); 146 return 1; 147 }, 148 }; 149 }, 150 151 get element() { 152 order.push("element"); 153 return { 154 toString() { 155 order.push("element toString"); 156 return "anyfunc"; 157 }, 158 }; 159 }, 160 }); 161 162 assert_array_equals(order, [ 163 "element", 164 "element toString", 165 "initial", 166 "initial valueOf", 167 "maximum", 168 "maximum valueOf", 169 ]); 170}, "Order of evaluation for descriptor"); 171 172test(() => { 173 const testObject = {}; 174 const argument = { "element": "externref", "initial": 3 }; 175 const table = new WebAssembly.Table(argument, testObject); 176 assert_equals(table.length, 3); 177 assert_equals(table.get(0), testObject); 178 assert_equals(table.get(1), testObject); 179 assert_equals(table.get(2), testObject); 180}, "initialize externref table with default value"); 181 182test(() => { 183 const argument = { "element": "i32", "initial": 3 }; 184 assert_throws_js(TypeError, () => new WebAssembly.Table(argument)); 185}, "initialize table with a wrong element value"); 186 187test(() => { 188 const builder = new WasmModuleBuilder(); 189 builder 190 .addFunction("fn", kSig_v_v) 191 .addBody([]) 192 .exportFunc(); 193 const bin = builder.toBuffer(); 194 const fn = new WebAssembly.Instance(new WebAssembly.Module(bin)).exports.fn; 195 const argument = { "element": "anyfunc", "initial": 3 }; 196 const table = new WebAssembly.Table(argument, fn); 197 assert_equals(table.length, 3); 198 assert_equals(table.get(0), fn); 199 assert_equals(table.get(1), fn); 200 assert_equals(table.get(2), fn); 201}, "initialize anyfunc table with default value"); 202 203test(() => { 204 const argument = { "element": "anyfunc", "initial": 3 }; 205 assert_throws_js(TypeError, () => new WebAssembly.Table(argument, {})); 206 assert_throws_js(TypeError, () => new WebAssembly.Table(argument, "cannot be used as a wasm function")); 207 assert_throws_js(TypeError, () => new WebAssembly.Table(argument, 37)); 208}, "initialize anyfunc table with a bad default value"); 209