diff options
Diffstat (limited to 'testing/web-platform/tests/wasm/jsapi/exception')
6 files changed, 343 insertions, 0 deletions
diff --git a/testing/web-platform/tests/wasm/jsapi/exception/basic.tentative.any.js b/testing/web-platform/tests/wasm/jsapi/exception/basic.tentative.any.js new file mode 100644 index 0000000000..cacce99d9c --- /dev/null +++ b/testing/web-platform/tests/wasm/jsapi/exception/basic.tentative.any.js @@ -0,0 +1,120 @@ +// META: global=window,worker,jsshell,shadowrealm +// META: script=/wasm/jsapi/wasm-module-builder.js + +function assert_throws_wasm(fn, message) { + try { + fn(); + assert_not_reached(`expected to throw with ${message}`); + } catch (e) { + assert_true(e instanceof WebAssembly.Exception, `Error should be a WebAssembly.Exception with ${message}`); + } +} + +promise_test(async () => { + const kSig_v_r = makeSig([kWasmExternRef], []); + const builder = new WasmModuleBuilder(); + const tagIndex = builder.addTag(kSig_v_r); + builder.addFunction("throw_param", kSig_v_r) + .addBody([ + kExprLocalGet, 0, + kExprThrow, tagIndex, + ]) + .exportFunc(); + const buffer = builder.toBuffer(); + const {instance} = await WebAssembly.instantiate(buffer, {}); + const values = [ + undefined, + null, + true, + false, + "test", + Symbol(), + 0, + 1, + 4.2, + NaN, + Infinity, + {}, + () => {}, + ]; + for (const v of values) { + assert_throws_wasm(() => instance.exports.throw_param(v), String(v)); + } +}, "Wasm function throws argument"); + +promise_test(async () => { + const builder = new WasmModuleBuilder(); + const tagIndex = builder.addTag(kSig_v_a); + builder.addFunction("throw_null", kSig_v_v) + .addBody([ + kExprRefNull, kAnyFuncCode, + kExprThrow, tagIndex, + ]) + .exportFunc(); + const buffer = builder.toBuffer(); + const {instance} = await WebAssembly.instantiate(buffer, {}); + assert_throws_wasm(() => instance.exports.throw_null()); +}, "Wasm function throws null"); + +promise_test(async () => { + const builder = new WasmModuleBuilder(); + const tagIndex = builder.addTag(kSig_v_i); + builder.addFunction("throw_int", kSig_v_v) + .addBody([ + ...wasmI32Const(7), + kExprThrow, tagIndex, + ]) + .exportFunc(); + const buffer = builder.toBuffer(); + const {instance} = await WebAssembly.instantiate(buffer, {}); + assert_throws_wasm(() => instance.exports.throw_int()); +}, "Wasm function throws integer"); + +promise_test(async () => { + const builder = new WasmModuleBuilder(); + const fnIndex = builder.addImport("module", "fn", kSig_v_v); + const tagIndex= builder.addTag(kSig_v_r); + builder.addFunction("catch_exception", kSig_r_v) + .addBody([ + kExprTry, kWasmStmt, + kExprCallFunction, fnIndex, + kExprCatch, tagIndex, + kExprReturn, + kExprEnd, + kExprRefNull, kExternRefCode, + ]) + .exportFunc(); + + const buffer = builder.toBuffer(); + + const error = new Error(); + const fn = () => { throw error }; + const {instance} = await WebAssembly.instantiate(buffer, { + module: { fn } + }); + assert_throws_exactly(error, () => instance.exports.catch_exception()); +}, "Imported JS function throws"); + +promise_test(async () => { + const builder = new WasmModuleBuilder(); + const fnIndex = builder.addImport("module", "fn", kSig_v_v); + builder.addFunction("catch_and_rethrow", kSig_r_v) + .addBody([ + kExprTry, kWasmStmt, + kExprCallFunction, fnIndex, + kExprCatchAll, + kExprRethrow, 0x00, + kExprEnd, + kExprRefNull, kExternRefCode, + ]) + .exportFunc(); + + const buffer = builder.toBuffer(); + + const error = new Error(); + const fn = () => { throw error }; + const {instance} = await WebAssembly.instantiate(buffer, { + module: { fn } + }); + assert_throws_exactly(error, () => instance.exports.catch_and_rethrow()); +}, "Imported JS function throws, Wasm catches and rethrows"); diff --git a/testing/web-platform/tests/wasm/jsapi/exception/constructor.tentative.any.js b/testing/web-platform/tests/wasm/jsapi/exception/constructor.tentative.any.js new file mode 100644 index 0000000000..a46d1816c3 --- /dev/null +++ b/testing/web-platform/tests/wasm/jsapi/exception/constructor.tentative.any.js @@ -0,0 +1,62 @@ +// META: global=window,dedicatedworker,jsshell,shadowrealm +// META: script=/wasm/jsapi/assertions.js + +test(() => { + assert_function_name( + WebAssembly.Exception, + "Exception", + "WebAssembly.Exception" + ); +}, "name"); + +test(() => { + assert_function_length(WebAssembly.Exception, 1, "WebAssembly.Exception"); +}, "length"); + +test(() => { + assert_throws_js(TypeError, () => new WebAssembly.Exception()); +}, "No arguments"); + +test(() => { + const tag = new WebAssembly.Tag({ parameters: [] }); + assert_throws_js(TypeError, () => WebAssembly.Exception(tag)); +}, "Calling"); + +test(() => { + const invalidArguments = [ + undefined, + null, + false, + true, + "", + "test", + Symbol(), + 1, + NaN, + {}, + ]; + for (const invalidArgument of invalidArguments) { + assert_throws_js( + TypeError, + () => new WebAssembly.Exception(invalidArgument), + `new Exception(${format_value(invalidArgument)})` + ); + } +}, "Invalid descriptor argument"); + +test(() => { + const typesAndArgs = [ + ["i32", 123n], + ["i32", Symbol()], + ["f32", 123n], + ["f64", 123n], + ["i64", undefined], + ]; + for (const typeAndArg of typesAndArgs) { + const tag = new WebAssembly.Tag({ parameters: [typeAndArg[0]] }); + assert_throws_js( + TypeError, + () => new WebAssembly.Exception(tag, typeAndArg[1]) + ); + } +}, "Invalid exception argument"); diff --git a/testing/web-platform/tests/wasm/jsapi/exception/getArg.tentative.any.js b/testing/web-platform/tests/wasm/jsapi/exception/getArg.tentative.any.js new file mode 100644 index 0000000000..87719c7ebd --- /dev/null +++ b/testing/web-platform/tests/wasm/jsapi/exception/getArg.tentative.any.js @@ -0,0 +1,54 @@ +// META: global=window,dedicatedworker,jsshell,shadowrealm +// META: script=/wasm/jsapi/memory/assertions.js + +test(() => { + const tag = new WebAssembly.Tag({ parameters: [] }); + const exn = new WebAssembly.Exception(tag, []); + assert_throws_js(TypeError, () => exn.getArg()); + assert_throws_js(TypeError, () => exn.getArg(tag)); +}, "Missing arguments"); + +test(() => { + const invalidValues = [undefined, null, true, "", Symbol(), 1, {}]; + const tag = new WebAssembly.Tag({ parameters: [] }); + const exn = new WebAssembly.Exception(tag, []); + for (argument of invalidValues) { + assert_throws_js(TypeError, () => exn.getArg(argument, 0)); + } +}, "Invalid exception argument"); + +test(() => { + const tag = new WebAssembly.Tag({ parameters: [] }); + const exn = new WebAssembly.Exception(tag, []); + assert_throws_js(RangeError, () => exn.getArg(tag, 1)); +}, "Index out of bounds"); + +test(() => { + const outOfRangeValues = [ + undefined, + NaN, + Infinity, + -Infinity, + -1, + 0x100000000, + 0x1000000000, + "0x100000000", + { + valueOf() { + return 0x100000000; + }, + }, + ]; + + const tag = new WebAssembly.Tag({ parameters: [] }); + const exn = new WebAssembly.Exception(tag, []); + for (const value of outOfRangeValues) { + assert_throws_js(RangeError, () => exn.getArg(tag, value)); + } +}, "Getting out-of-range argument"); + +test(() => { + const tag = new WebAssembly.Tag({ parameters: ["i32"] }); + const exn = new WebAssembly.Exception(tag, [42]); + assert_equals(exn.getArg(tag, 0), 42); +}, "getArg"); diff --git a/testing/web-platform/tests/wasm/jsapi/exception/identity.tentative.any.js b/testing/web-platform/tests/wasm/jsapi/exception/identity.tentative.any.js new file mode 100644 index 0000000000..2675668ec7 --- /dev/null +++ b/testing/web-platform/tests/wasm/jsapi/exception/identity.tentative.any.js @@ -0,0 +1,61 @@ +// META: global=window,dedicatedworker,jsshell,shadowrealm +// META: script=/wasm/jsapi/assertions.js +// META: script=/wasm/jsapi/wasm-module-builder.js + +test(() => { + const tag = new WebAssembly.Tag({ parameters: ["i32"] }); + const exn = new WebAssembly.Exception(tag, [42]); + const exn_same_payload = new WebAssembly.Exception(tag, [42]); + const exn_diff_payload = new WebAssembly.Exception(tag, [53]); + + const builder = new WasmModuleBuilder(); + const jsfuncIndex = builder.addImport("module", "jsfunc", kSig_v_v); + const tagIndex = builder.addImportedTag("module", "tag", kSig_v_i); + const imports = { + module: { + jsfunc: function() { throw exn; }, + tag: tag + } + }; + + builder + .addFunction("catch_rethrow", kSig_v_v) + .addBody([ + kExprTry, kWasmStmt, + kExprCallFunction, jsfuncIndex, + kExprCatch, tagIndex, + kExprDrop, + kExprRethrow, 0x00, + kExprEnd + ]) + .exportFunc(); + + builder + .addFunction("catch_all_rethrow", kSig_v_v) + .addBody([ + kExprTry, kWasmStmt, + kExprCallFunction, jsfuncIndex, + kExprCatchAll, + kExprRethrow, 0x00, + kExprEnd + ]) + .exportFunc(); + + const buffer = builder.toBuffer(); + WebAssembly.instantiate(buffer, imports).then(result => { + try { + result.instance.exports.catch_rethrow(); + } catch (e) { + assert_equals(e, exn); + assert_not_equals(e, exn_same_payload); + assert_not_equals(e, exn_diff_payload); + } + try { + result.instance.exports.catch_all_rethrow(); + } catch (e) { + assert_equals(e, exn); + assert_not_equals(e, exn_same_payload); + assert_not_equals(e, exn_diff_payload); + } + }); +}, "Identity check"); diff --git a/testing/web-platform/tests/wasm/jsapi/exception/is.tentative.any.js b/testing/web-platform/tests/wasm/jsapi/exception/is.tentative.any.js new file mode 100644 index 0000000000..840d00bf0d --- /dev/null +++ b/testing/web-platform/tests/wasm/jsapi/exception/is.tentative.any.js @@ -0,0 +1,25 @@ +// META: global=window,dedicatedworker,jsshell,shadowrealm +// META: script=/wasm/jsapi/memory/assertions.js + +test(() => { + const tag = new WebAssembly.Tag({ parameters: [] }); + const exn = new WebAssembly.Exception(tag, []); + assert_throws_js(TypeError, () => exn.is()); +}, "Missing arguments"); + +test(() => { + const invalidValues = [undefined, null, true, "", Symbol(), 1, {}]; + const tag = new WebAssembly.Tag({ parameters: [] }); + const exn = new WebAssembly.Exception(tag, []); + for (argument of invalidValues) { + assert_throws_js(TypeError, () => exn.is(argument)); + } +}, "Invalid exception argument"); + +test(() => { + const tag1 = new WebAssembly.Tag({ parameters: ["i32"] }); + const tag2 = new WebAssembly.Tag({ parameters: ["i32"] }); + const exn = new WebAssembly.Exception(tag1, [42]); + assert_true(exn.is(tag1)); + assert_false(exn.is(tag2)); +}, "is"); diff --git a/testing/web-platform/tests/wasm/jsapi/exception/toString.tentative.any.js b/testing/web-platform/tests/wasm/jsapi/exception/toString.tentative.any.js new file mode 100644 index 0000000000..6885cf0deb --- /dev/null +++ b/testing/web-platform/tests/wasm/jsapi/exception/toString.tentative.any.js @@ -0,0 +1,21 @@ +// META: global=window,dedicatedworker,jsshell,shadowrealm + +test(() => { + const argument = { parameters: [] }; + const tag = new WebAssembly.Tag(argument); + const exn = new WebAssembly.Exception(tag, []); + assert_class_string(exn, "WebAssembly.Exception"); +}, "Object.prototype.toString on an Exception"); + +test(() => { + assert_own_property(WebAssembly.Exception.prototype, Symbol.toStringTag); + + const propDesc = Object.getOwnPropertyDescriptor( + WebAssembly.Exception.prototype, + Symbol.toStringTag + ); + assert_equals(propDesc.value, "WebAssembly.Exception", "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"); |