Source code

Revision control

Copy as Markdown

Other Tools

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