| // META: global=jsshell | |
| // META: script=/wasm/jsapi/wasm-module-builder.js | |
| // META: script=assertions.js | |
| let functions; | |
| setup(() => { | |
| const builder = new WasmModuleBuilder(); | |
| builder | |
| .addFunction("fn", kSig_v_d) | |
| .addBody([]) | |
| .exportFunc(); | |
| builder | |
| .addFunction("fn2", kSig_v_v) | |
| .addBody([]) | |
| .exportFunc(); | |
| const buffer = builder.toBuffer() | |
| const module = new WebAssembly.Module(buffer); | |
| const instance = new WebAssembly.Instance(module, {}); | |
| functions = instance.exports; | |
| }); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 5 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_throws(new TypeError(), () => table.get()); | |
| }, "Missing arguments: get"); | |
| test(t => { | |
| const thisValues = [ | |
| undefined, | |
| null, | |
| true, | |
| "", | |
| Symbol(), | |
| 1, | |
| {}, | |
| WebAssembly.Table, | |
| WebAssembly.Table.prototype, | |
| ]; | |
| const argument = { | |
| valueOf: t.unreached_func("Should not touch the argument (valueOf)"), | |
| toString: t.unreached_func("Should not touch the argument (toString)"), | |
| }; | |
| const fn = WebAssembly.Table.prototype.get; | |
| for (const thisValue of thisValues) { | |
| assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`); | |
| } | |
| }, "Branding: get"); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 5 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_throws(new TypeError(), () => table.set()); | |
| assert_throws(new TypeError(), () => table.set(0)); | |
| }, "Missing arguments: set"); | |
| test(t => { | |
| const thisValues = [ | |
| undefined, | |
| null, | |
| true, | |
| "", | |
| Symbol(), | |
| 1, | |
| {}, | |
| WebAssembly.Table, | |
| WebAssembly.Table.prototype, | |
| ]; | |
| const argument = { | |
| valueOf: t.unreached_func("Should not touch the argument (valueOf)"), | |
| toString: t.unreached_func("Should not touch the argument (toString)"), | |
| }; | |
| const fn = WebAssembly.Table.prototype.set; | |
| for (const thisValue of thisValues) { | |
| assert_throws(new TypeError(), () => fn.call(thisValue, argument, null), `this=${format_value(thisValue)}`); | |
| } | |
| }, "Branding: set"); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 5 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_equal_to_array(table, [null, null, null, null, null]); | |
| const {fn, fn2} = functions; | |
| assert_equals(table.set(0, fn), undefined, "set() returns undefined."); | |
| table.set(2, fn2); | |
| table.set(4, fn); | |
| assert_equal_to_array(table, [fn, null, fn2, null, fn]); | |
| table.set(0, null); | |
| assert_equal_to_array(table, [null, null, fn2, null, fn]); | |
| }, "Basic"); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 5 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_equal_to_array(table, [null, null, null, null, null]); | |
| const {fn, fn2} = functions; | |
| table.set(0, fn); | |
| table.set(2, fn2); | |
| table.set(4, fn); | |
| assert_equal_to_array(table, [fn, null, fn2, null, fn]); | |
| table.grow(4); | |
| assert_equal_to_array(table, [fn, null, fn2, null, fn, null, null, null, null]); | |
| }, "Growing"); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 5 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_equal_to_array(table, [null, null, null, null, null]); | |
| const {fn} = functions; | |
| // -1 is the wrong type hence the type check on entry gets this | |
| // before the range check does. | |
| assert_throws(new TypeError(), () => table.set(-1, fn)); | |
| assert_throws(new RangeError(), () => table.set(5, fn)); | |
| assert_equal_to_array(table, [null, null, null, null, null]); | |
| }, "Setting out-of-bounds"); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 1 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_equal_to_array(table, [null]); | |
| const invalidArguments = [ | |
| undefined, | |
| true, | |
| false, | |
| "test", | |
| Symbol(), | |
| 7, | |
| NaN, | |
| {}, | |
| ]; | |
| for (const argument of invalidArguments) { | |
| assert_throws(new TypeError(), () => table.set(0, argument), | |
| `set(${format_value(argument)})`); | |
| } | |
| assert_equal_to_array(table, [null]); | |
| }, "Setting non-function"); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 1 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_equal_to_array(table, [null]); | |
| const fn = function() {}; | |
| assert_throws(new TypeError(), () => table.set(0, fn)); | |
| assert_equal_to_array(table, [null]); | |
| }, "Setting non-wasm function"); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 1 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_equal_to_array(table, [null]); | |
| const fn = () => {}; | |
| assert_throws(new TypeError(), () => table.set(0, fn)); | |
| assert_equal_to_array(table, [null]); | |
| }, "Setting non-wasm arrow function"); | |
| const outOfRangeValues = [ | |
| undefined, | |
| NaN, | |
| Infinity, | |
| -Infinity, | |
| -1, | |
| 0x100000000, | |
| 0x1000000000, | |
| "0x100000000", | |
| { valueOf() { return 0x100000000; } }, | |
| ]; | |
| for (const value of outOfRangeValues) { | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 1 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_throws(new TypeError(), () => table.get(value)); | |
| }, `Getting out-of-range argument: ${format_value(value)}`); | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 1 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_throws(new TypeError(), () => table.set(value, null)); | |
| }, `Setting out-of-range argument: ${format_value(value)}`); | |
| } | |
| test(() => { | |
| const argument = { "element": "anyfunc", "initial": 1 }; | |
| const table = new WebAssembly.Table(argument); | |
| let called = 0; | |
| const value = { | |
| valueOf() { | |
| called++; | |
| return 0; | |
| }, | |
| }; | |
| assert_throws(new TypeError(), () => table.set(value, {})); | |
| assert_equals(called, 1); | |
| }, "Order of argument conversion"); | |
| test(() => { | |
| const {fn} = functions; | |
| const argument = { "element": "anyfunc", "initial": 1 }; | |
| const table = new WebAssembly.Table(argument); | |
| assert_equals(table.get(0, {}), null); | |
| assert_equals(table.set(0, fn, {}), undefined); | |
| }, "Stray argument"); |