-
Notifications
You must be signed in to change notification settings - Fork 36
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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"); | ||
|
||
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 } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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"); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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? 🤷🏻
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.