Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

// 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");