1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
// 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");
|