150 lines
No EOL
4.6 KiB
JavaScript
150 lines
No EOL
4.6 KiB
JavaScript
// META: global=window,dedicatedworker,jsshell
|
|
// META: script=/wasm/jsapi/wasm-module-builder.js
|
|
// META: script=/wasm/jsapi/jspi/testharness-additions.js
|
|
|
|
promise_test(t => {
|
|
let tag = new WebAssembly.Tag({
|
|
parameters: []
|
|
});
|
|
let builder = new WasmModuleBuilder();
|
|
import_index = builder.addImport('m', 'import', kSig_i_i);
|
|
tag_index = builder.addImportedTag('m', 'tag', kSig_v_v);
|
|
builder.addFunction("test", kSig_i_i)
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, import_index,
|
|
kExprThrow, tag_index
|
|
]).exportFunc();
|
|
|
|
function js_import() {
|
|
return Promise.resolve();
|
|
};
|
|
let wasm_js_import = new WebAssembly.Suspending(js_import);
|
|
|
|
let instance = builder.instantiate({
|
|
m: {
|
|
import: wasm_js_import,
|
|
tag: tag
|
|
}
|
|
});
|
|
let wrapped_export = WebAssembly.promising(instance.exports.test);
|
|
let export_promise = wrapped_export();
|
|
assert_true(export_promise instanceof Promise);
|
|
return promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise);
|
|
}, "Throw after the first suspension");
|
|
|
|
// Throw an exception before suspending. The export wrapper should return a
|
|
// promise rejected with the exception.
|
|
promise_test(async (t) => {
|
|
let tag = new WebAssembly.Tag({
|
|
parameters: []
|
|
});
|
|
let builder = new WasmModuleBuilder();
|
|
tag_index = builder.addImportedTag('m', 'tag', kSig_v_v);
|
|
builder.addFunction("test", kSig_i_v)
|
|
.addBody([
|
|
kExprThrow, tag_index
|
|
]).exportFunc();
|
|
|
|
let instance = builder.instantiate({
|
|
m: {
|
|
tag: tag
|
|
}
|
|
});
|
|
let wrapped_export = WebAssembly.promising(instance.exports.test);
|
|
let export_promise = wrapped_export();
|
|
|
|
promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise);
|
|
}, "Throw before suspending");
|
|
|
|
// Throw an exception after the first resume event, which propagates to the
|
|
// promise wrapper.
|
|
promise_test(async (t) => {
|
|
let tag = new WebAssembly.Tag({
|
|
parameters: []
|
|
});
|
|
let builder = new WasmModuleBuilder();
|
|
import_index = builder.addImport('m', 'import', kSig_i_v);
|
|
tag_index = builder.addImportedTag('m', 'tag', kSig_v_v);
|
|
builder.addFunction("test", kSig_i_v)
|
|
.addBody([
|
|
kExprCallFunction, import_index,
|
|
kExprThrow, tag_index
|
|
]).exportFunc();
|
|
|
|
function js_import() {
|
|
return Promise.resolve(42);
|
|
};
|
|
let wasm_js_import = new WebAssembly.Suspending(js_import);
|
|
|
|
let instance = builder.instantiate({
|
|
m: {
|
|
import: wasm_js_import,
|
|
tag: tag
|
|
}
|
|
});
|
|
let wrapped_export = WebAssembly.promising(instance.exports.test);
|
|
let export_promise = wrapped_export();
|
|
|
|
promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise);
|
|
}, "Throw and propagate via Promise");
|
|
|
|
promise_test(async (t) => {
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addFunction("test", kSig_i_v)
|
|
.addBody([
|
|
kExprCallFunction, 0
|
|
]).exportFunc();
|
|
let instance = builder.instantiate();
|
|
let wrapper = WebAssembly.promising(instance.exports.test);
|
|
|
|
// Stack overflow has undefined behavior -- check if an exception was thrown.
|
|
let thrown = false;
|
|
try {
|
|
await wrapper();
|
|
} catch (e) {
|
|
thrown = true;
|
|
}
|
|
assert_true(thrown);
|
|
}, "Stack overflow");
|
|
|
|
promise_test(async (t) => {
|
|
// The call stack of this test looks like:
|
|
// export1 -> import1 -> export2 -> import2
|
|
// Where export1 is "promising" and import2 is "suspending". Returning a
|
|
// promise from import2 should trap because of the JS import in the middle.
|
|
let builder = new WasmModuleBuilder();
|
|
let import1_index = builder.addImport("m", "import1", kSig_i_v);
|
|
let import2_index = builder.addImport("m", "import2", kSig_i_v);
|
|
builder.addFunction("export1", kSig_i_v)
|
|
.addBody([
|
|
// export1 -> import1 (unwrapped)
|
|
kExprCallFunction, import1_index,
|
|
]).exportFunc();
|
|
builder.addFunction("export2", kSig_i_v)
|
|
.addBody([
|
|
// export2 -> import2 (suspending)
|
|
kExprCallFunction, import2_index,
|
|
]).exportFunc();
|
|
let instance;
|
|
|
|
function import1() {
|
|
// import1 -> export2 (unwrapped)
|
|
instance.exports.export2();
|
|
}
|
|
|
|
function import2() {
|
|
return Promise.resolve(0);
|
|
}
|
|
import2 = new WebAssembly.Suspending(import2);
|
|
instance = builder.instantiate({
|
|
'm': {
|
|
'import1': import1,
|
|
'import2': import2
|
|
}
|
|
});
|
|
// export1 (promising)
|
|
let wrapper = WebAssembly.promising(instance.exports.export1);
|
|
promise_rejects_js(t, WebAssembly.SuspendError, wrapper(),
|
|
"trying to suspend JS frames");
|
|
}, "Try to suspend JS"); |