Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[js-api] Add tests for WebAssembly.JSTag #319

Merged
merged 2 commits into from
Jul 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions test/js-api/exception/jsTag.tentative.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// META: global=window,dedicatedworker,jsshell,shadowrealm
// META: script=/wasm/jsapi/assertions.js
// META: script=/wasm/jsapi/wasm-module-builder.js

test(() => {
assert_throws_js(TypeError, () => new WebAssembly.Exception(WebAssembly.JSTag, [{}]))
}, "Creating a WebAssembly.Exception with JSTag explicitly is not allowed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I'm showing my lack of knowledge about the details of the test infra, but does this assertion check the exact text of the error message? The spec mandates what kind of exception should be thrown (TypeError), but not the text.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this string is checked against anything else. So I just used it to describe what the tests were about. Maybe I'm abusing it? 🤷🏻

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it's fine as long as the test won't fail because of different error messages.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is just the name of the subtest.


promise_test(async () => {
const builder = new WasmModuleBuilder();
const jsTag = builder.addImportedTag("module", "JSTag", kSig_v_r);

const throwRefFn = builder.addImport("module", "throw_ref", kSig_r_r);
const sig_r_v = builder.addType(kSig_r_v);
const kSig_re_v = makeSig([], [kExternRefCode, kExnRefCode]);
const sig_re_v = builder.addType(kSig_re_v);

// Calls throw_ref, catches an exception with 'try_table - catch JSTag', and
// returns it
builder.addFunction("catch_js_tag_and_return", kSig_r_r)
.addBody([
kExprBlock, sig_r_v,
kExprTryTable, sig_r_v, 1,
kCatchNoRef, jsTag, 0,
kExprLocalGet, 0,
kExprCallFunction, throwRefFn,
kExprEnd,
kExprEnd,
])
.exportFunc();

// Calls throw_ref, catches an exception with 'try_table - catch_ref JSTag',
// and returns it
builder.addFunction("catch_ref_js_tag_and_return", kSig_r_r)
.addBody([
kExprBlock, sig_re_v,
kExprTryTable, sig_r_v, 1,
kCatchRef, jsTag, 0,
kExprLocalGet, 0,
kExprCallFunction, throwRefFn,
kExprEnd,
kExprReturn,
kExprEnd,
kExprDrop,
])
.exportFunc();

// Calls throw_ref, catches an exception with 'try_table - catch_ref JSTag',
// and rethrows it (with throw_ref)
builder.addFunction("catch_ref_js_tag_and_throw_ref", kSig_r_r)
.addBody([
kExprBlock, sig_re_v,
kExprTryTable, sig_r_v, 1,
kCatchRef, jsTag, 0,
kExprLocalGet, 0,
kExprCallFunction, throwRefFn,
kExprEnd,
kExprReturn,
kExprEnd,
kExprThrowRef,
])
.exportFunc();

function throw_ref(x) {
throw x;
}
const buffer = builder.toBuffer();
const {instance} = await WebAssembly.instantiate(buffer, {
module: { throw_ref, JSTag: WebAssembly.JSTag }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be throw_ref: throw_ref,?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works, but it looks in case the imported name and the external name are the same, just writing it once seems to have the same effect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is the shorthand syntax in JS object initializers.

});

const obj = {};
const wasmTag = new WebAssembly.Tag({parameters:['externref']});
const exn = new WebAssembly.Exception(wasmTag, [obj]);

// Test catch w/ return:
// This throws obj as a JS exception so it should be caught by the program and
// be returned as the original obj.
assert_equals(obj, instance.exports.catch_js_tag_and_return(obj));
// This is a WebAssembly.Exception, so the exception should just pass through
// the program without being caught.
assert_throws_exactly(exn, () => instance.exports.catch_js_tag_and_return(exn));

// Test catch_ref w/ return:
// This throws obj as a JS exception so it should be caught by the program and
// be returned as the original obj.
assert_equals(obj, instance.exports.catch_ref_js_tag_and_return(obj));
// This is a WebAssembly.Exception, so the exception should just pass through
// the program without being caught.
assert_throws_exactly(exn, () => instance.exports.catch_ref_js_tag_and_return(exn));

// Test catch_ref w/ throw_ref:
// This throws obj as a JS exception so it should be caught by the program and
// be rethrown.
assert_throws_exactly(obj, () => instance.exports.catch_ref_js_tag_and_throw_ref(obj));
// This is a WebAssembly.Exception, so the exception should just pass through
// the program without being caught.
assert_throws_exactly(exn, () => instance.exports.catch_ref_js_tag_and_throw_ref(exn));
}, "JS tag catching tests");

promise_test(async () => {
const builder = new WasmModuleBuilder();
const jsTag = builder.addImportedTag("module", "JSTag", kSig_v_r);

// Throw a JS object with WebAssembly.JSTag and check that we can catch it
// as-is from JavaScript.
builder.addFunction("throw_js_tag", kSig_v_r)
.addBody([
kExprLocalGet, 0,
kExprThrow, jsTag,
])
.exportFunc();

const buffer = builder.toBuffer();
const {instance} = await WebAssembly.instantiate(buffer, {
module: { JSTag: WebAssembly.JSTag }
});

const obj = {};
assert_throws_exactly(obj, () => instance.exports.throw_js_tag(obj));
}, "JS tag throwing test");
Loading