Skip to content

Commit 7154a97

Browse files
authored
Merge branch 'main' into resolve
2 parents e72cdc0 + ce7705f commit 7154a97

File tree

2 files changed

+54
-35
lines changed

2 files changed

+54
-35
lines changed

document/js-api/index.bs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [
11711171
1. Let |args| be the result of [=coerce JavaScript arguments|coercing arguments=] (|functype|,|argValues|).
11721172
1. Let (|store|, |ret|) be the result of [=func_invoke=](|store|, |funcaddr|, |args|).
11731173
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
1174-
1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by <a href="#errors">the WebAssembly error mapping</a>.
1174+
1. If |ret| is [=error=], throw an exception. This exception must be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by <a href="#errors">the WebAssembly error mapping</a>.
11751175
1. If |ret| is [=THROW=] [=ref.exn=] |exnaddr|, then:
11761176
1. Let |tagaddr| be [=exn_tag=](|store|, |exnaddr|).
11771177
1. Let |payload| be [=exn_read=](|store|, |exnaddr|).
@@ -1438,7 +1438,7 @@ interface Suspending {
14381438
1. Add an entry mapping |ec| to [=active=] in |map|.
14391439
1. Let (|store|, |result|) be the result of [=func_invoke=](|store|, |funcaddr|, |args|).
14401440
1. Assert: If control reaches here, we have done waiting for suspended imports.
1441-
1. If the entry for |ec| in |map| is not [=active=] then throw a WebAssembly {{RuntimeError}} exception. Otherwise, remove the entry for |ec| from [=map=].
1441+
1. If the entry for |ec| in |map| is not [=active=] then throw a WebAssembly {{SuspendError}} exception. Otherwise, remove the entry for |ec| from [=map=].
14421442
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
14431443
1. If |result| is [=error=], throw a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by <a href="#errors">the WebAssembly error mapping</a>.
14441444
1. Otherwise, if |result| is of the form [=throw=] exnaddr,
@@ -1477,7 +1477,7 @@ To <dfn>create a suspending function</dfn> from a JavaScript function |func|, wi
14771477
1. Let |async_context| be the [=surrounding agent=]'s [=running execution context=].
14781478
1. Let |map| be the [=surrounding agent=]'s associated [=Execution Context Status map=].
14791479
1. If the entry for |async_context| in |map| is not [=active=], then:
1480-
1. Perform [=throw a JavaScript exception=] with a {{RuntimeError}} exception.
1480+
1. Perform [=throw a JavaScript exception=] with a {{SuspendError}} exception.
14811481
1. [=Prepare to run script=] with |relevant settings|.
14821482
1. [=Prepare to run a callback=] with |stored settings|.
14831483
1. Let [|parameters|][|resultTypes|] be |functype|.
@@ -1812,19 +1812,19 @@ To <dfn>get the JavaScript exception tag</dfn>, perform the following steps:
18121812

18131813
<h3 id="error-objects">Error Objects</h3>
18141814

1815-
WebAssembly defines the following Error classes: <dfn exception>CompileError</dfn>, <dfn exception>LinkError</dfn>, and <dfn exception>RuntimeError</dfn>.
1815+
WebAssembly defines the following Error classes: <dfn exception>CompileError</dfn>, <dfn exception>LinkError</dfn>, <dfn exception>RuntimeError</dfn>, and <dfn exception>SuspendError</dfn>.
18161816

18171817
<div algorithm="create the WebAssembly namespace object">
18181818
When the [=namespace object=] for the {{WebAssembly}} namespace is [=create a namespace object|created=], the following steps must be run:
18191819

18201820
1. Let |namespaceObject| be the [=namespace object=].
1821-
1. [=list/iterate|For each=] |error| of « "CompileError", "LinkError", "RuntimeError" »,
1821+
1. [=list/iterate|For each=] |error| of « "CompileError", "LinkError", "RuntimeError", "SuspendError" »,
18221822
1. Let |constructor| be a new object, implementing the [=NativeError Object Structure=], with <var ignore>NativeError</var> set to |error|.
18231823
1. [=!=] [$DefineMethodProperty$](|namespaceObject|, |error|, |constructor|, false).
18241824

18251825
</div>
18261826

1827-
Note: This defines {{CompileError}}, {{LinkError}}, and {{RuntimeError}} classes on the {{WebAssembly}} namespace, which are produced by the APIs defined in this specification.
1827+
Note: This defines {{CompileError}}, {{LinkError}}, {{RuntimeError}}, and {{SuspendError}} classes on the {{WebAssembly}} namespace, which are produced by the APIs defined in this specification.
18281828
They expose the same interface as native JavaScript errors like {{TypeError}} and {{RangeError}}.
18291829

18301830
Note: It is not currently possible to define this behavior using Web IDL.

test/js-api/js-promise-integration/js-promise-integration.any.js

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
// META: global=jsshell
22
// META: script=/wasm/jsapi/wasm-module-builder.js
33

4-
function Promising(wasm_export) {
5-
return WebAssembly.promising(wasm_export);
6-
}
7-
8-
function Suspending(jsFun){
9-
return new WebAssembly.Suspending(jsFun);
10-
}
11-
124
// Test for invalid wrappers
135
test(() => {
146
assert_throws(TypeError, () => WebAssembly.promising({}),
@@ -52,9 +44,9 @@ promise_test(async () => {
5244
kExprLocalGet, 0,
5345
kExprCallFunction, import_index, // suspend
5446
]).exportFunc();
55-
let js_import = Suspending(() => Promise.resolve(42));
47+
let js_import = WebAssembly.Suspending(() => Promise.resolve(42));
5648
let instance = builder.instantiate({m: {import: js_import}});
57-
let wrapped_export = Promising(instance.exports.test);
49+
let wrapped_export = WebAssembly.promising(instance.exports.test);
5850
let export_promise = wrapped_export();
5951
assert_true(export_promise instanceof Promise);
6052
assert_equals(await export_promise, 42);
@@ -91,9 +83,9 @@ promise_test(async () => {
9183
function js_import() {
9284
return Promise.resolve(++i);
9385
};
94-
let wasm_js_import = Suspending(js_import);
86+
let wasm_js_import = WebAssembly.Suspending(js_import);
9587
let instance = builder.instantiate({m: {import: wasm_js_import}});
96-
let wrapped_export = Promising(instance.exports.test);
88+
let wrapped_export = WebAssembly.promising(instance.exports.test);
9789
let export_promise = wrapped_export();
9890
assert_equals(instance.exports.g.value, 0);
9991
assert_true(export_promise instanceof Promise);
@@ -154,11 +146,11 @@ promise_test(async () => {
154146
kExprCallFunction, import42_index, // suspend?
155147
kExprCallFunction, importSetA_index
156148
]).exportFunc();
157-
let import42 = Suspending(()=>Promise.resolve(42));
149+
let import42 = WebAssembly.Suspending(()=>Promise.resolve(42));
158150
let instance = builder.instantiate({m: {import42: import42,
159151
setA:AbeforeB.setA}});
160152

161-
let wrapped_export = Promising(instance.exports.test);
153+
let wrapped_export = WebAssembly.promising(instance.exports.test);
162154

163155
// AbeforeB.showAbeforeB();
164156
let exported_promise = wrapped_export();
@@ -183,11 +175,11 @@ promise_test(async () => {
183175
kExprCallFunction, import42_index, // suspend?
184176
kExprCallFunction, importSetA_index
185177
]).exportFunc();
186-
let import42 = Suspending(()=>42);
178+
let import42 = WebAssembly.Suspending(()=>42);
187179
let instance = builder.instantiate({m: {import42: import42,
188180
setA:AbeforeB.setA}});
189181

190-
let wrapped_export = Promising(instance.exports.test);
182+
let wrapped_export = WebAssembly.promising(instance.exports.test);
191183

192184
let exported_promise = wrapped_export();
193185
AbeforeB.setB();
@@ -213,10 +205,10 @@ test(t => {
213205
function js_import() {
214206
return Promise.resolve();
215207
};
216-
let wasm_js_import = Suspending(js_import);
208+
let wasm_js_import = WebAssembly.Suspending(js_import);
217209

218210
let instance = builder.instantiate({m: {import: wasm_js_import, tag: tag}});
219-
let wrapped_export = Promising(instance.exports.test);
211+
let wrapped_export = WebAssembly.promising(instance.exports.test);
220212
let export_promise = wrapped_export();
221213
assert_true(export_promise instanceof Promise);
222214
promise_rejects(t, new WebAssembly.Exception(tag, []), export_promise);
@@ -239,10 +231,10 @@ promise_test(async (t) => {
239231
function js_import() {
240232
return Promise.reject(new WebAssembly.Exception(tag, [42]));
241233
};
242-
let wasm_js_import = Suspending(js_import);
234+
let wasm_js_import = WebAssembly.Suspending(js_import);
243235

244236
let instance = builder.instantiate({m: {import: wasm_js_import, tag: tag}});
245-
let wrapped_export = Promising(instance.exports.test);
237+
let wrapped_export = WebAssembly.promising(instance.exports.test);
246238
let export_promise = wrapped_export();
247239
assert_true(export_promise instanceof Promise);
248240
assert_equals(await export_promise, 42);
@@ -273,14 +265,14 @@ async function TestNestedSuspenders(suspend) {
273265
kExprCallFunction, inner_index
274266
]).exportFunc();
275267

276-
let inner = Suspending(() => suspend ? Promise.resolve(42) : 43);
268+
let inner = WebAssembly.Suspending(() => suspend ? Promise.resolve(42) : 43);
277269

278270
let export_inner;
279-
let outer = Suspending(() => export_inner());
271+
let outer = WebAssembly.Suspending(() => export_inner());
280272

281273
let instance = builder.instantiate({m: {inner, outer}});
282-
export_inner = Promising(instance.exports.inner);
283-
let export_outer = Promising(instance.exports.outer);
274+
export_inner = WebAssembly.promising(instance.exports.inner);
275+
let export_outer = WebAssembly.promising(instance.exports.outer);
284276
let result = export_outer();
285277
assert_true(result instanceof Promise);
286278
if(suspend)
@@ -310,11 +302,11 @@ test(() => {
310302
.addBody([
311303
kExprLocalGet, 0
312304
]).exportFunc();
313-
let js_import = Suspending(() => Promise.resolve(42));
305+
let js_import = WebAssembly.Suspending(() => Promise.resolve(42));
314306
let instance = builder.instantiate({m: {import: js_import}});
315-
let suspender = Promising(instance.exports.return_suspender)();
307+
let suspender = WebAssembly.promising(instance.exports.return_suspender)();
316308
for (s of [suspender, null, undefined, {}]) {
317-
assert_throws(WebAssembly.RuntimeError, () => instance.exports.test(s));
309+
assert_throws(WebAssembly.SuspendError, () => instance.exports.test(s));
318310
}
319311
}, "Call import with an invalid suspender");
320312

@@ -438,8 +430,7 @@ promise_test(async (t) => {
438430
}});
439431
// export1 (promising)
440432
let wrapper = WebAssembly.promising(instance.exports.export1);
441-
promise_rejects(t, new WebAssembly.RuntimeError(), wrapper(),
442-
/trying to suspend JS frames/);
433+
promise_rejects(t, new WebAssembly.SuspendError(), wrapper());
443434
});
444435

445436
promise_test(async () => {
@@ -465,3 +456,31 @@ promise_test(async () => {
465456
let wrapped_export = WebAssembly.promising(instance2.exports.main);
466457
assert_equals(await wrapped_export(), 3);
467458
});
459+
460+
test(() => {
461+
let builder = new WasmModuleBuilder();
462+
let js_tag = builder.addImportedTag("", "tag", kSig_v_r);
463+
try_sig_index = builder.addType(kSig_i_v);
464+
465+
let promise42 = new WebAssembly.Suspending(() => Promise.resolve(42));
466+
let kPromise42Ref = builder.addImport("", "promise42", kSig_i_v);
467+
468+
builder.addFunction("test", kSig_i_v)
469+
.addBody([
470+
kExprTry, try_sig_index,
471+
kExprCallFunction, kPromise42Ref,
472+
kExprReturn, // If there was no trap or exception, return
473+
kExprCatch, js_tag,
474+
kExprI32Const, 43,
475+
kExprReturn,
476+
kExprEnd,
477+
])
478+
.exportFunc();
479+
480+
let instance = builder.instantiate({"": {
481+
promise42: promise42,
482+
tag: WebAssembly.JSTag,
483+
}});
484+
485+
assert_equals(43, instance.exports.test());
486+
},"catch the bad suspension");

0 commit comments

Comments
 (0)