Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 423f261

Browse files
authored
[js-api] Add stack trace support and preserve identity of JS exception values passing through WebAssembly. (#218)
1 parent 2429b1f commit 423f261

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

document/js-api/index.bs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,12 +1040,12 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [
10401040
1. [=list/Append=] [=ToWebAssemblyValue=](|arg|, |t|) to |args|.
10411041
1. Set |i| to |i| + 1.
10421042
1. Let (|store|, |ret|) be the result of [=func_invoke=](|store|, |funcaddr|, |args|).
1043-
1. Note: The expectation is that [=func_invoke=] will be updated to return (|store|, <var ignore>val</var>* | [=error=] | (exception |exntag| |payload|)).
1043+
1. Note: The expectation is that [=func_invoke=] will be updated to return (|store|, <var ignore>val</var>* | [=error=] | (exception |exntag| |payload| |opaqueData|)).
10441044
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
10451045
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>.
1046-
1. If |ret| is exception |exntag| |payload|, then
1047-
1. If |exntag| is the [=JavaScript exception tag=], then
1048-
1. Let « [=ref.extern=] |externaddr| » be |payload|.
1046+
1. If |ret| is exception |exntag| |payload| |opaqueData|, then
1047+
1. If |opaqueData| is not [=ref.null=] [=externref=],
1048+
1. Let « [=ref.extern=] |externaddr| » be |opaqueData|.
10491049
1. Throw the result of [=retrieving an extern value=] from |externaddr|.
10501050
1. Let |exception| be [=create an Exception object|a new Exception=] for |exntag| and |payload|.
10511051
1. Throw |exception|.
@@ -1107,8 +1107,9 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not
11071107
1. Let |payload| be |v|.\[[Payload]].
11081108
1. Otherwise,
11091109
1. Let |type| be the [=JavaScript exception tag=].
1110-
1. Let |payload| be [=ToWebAssemblyValue=](|v|, [=externref=]).
1111-
1. [=WebAssembly/Throw=] with |type| and |payload|.
1110+
1. Let |payload| be « ».
1111+
1. Let |opaqueData| be [=ToWebAssemblyValue=](|v|, [=externref=])
1112+
1. [=WebAssembly/Throw=] with |type|, |payload| and |opaqueData|.
11121113
1. Otherwise, return |result|.\[[Value]].
11131114
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
11141115
1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|).
@@ -1258,20 +1259,25 @@ Advisement: This method is only expected to be implemented or shipped when both
12581259
<h4 id="runtime-exceptions">Runtime exceptions</h4>
12591260

12601261
<pre class="idl">
1262+
dictionary ExceptionOptions {
1263+
boolean traceStack = false;
1264+
};
1265+
12611266
[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
12621267
interface Exception {
1263-
constructor(Tag exceptionTag, sequence&lt;any> payload);
1268+
constructor(Tag exceptionTag, sequence&lt;any> payload, optional ExceptionOptions options = {});
12641269
any getArg(Tag exceptionTag, unsigned long index);
12651270
boolean is(Tag exceptionTag);
1271+
readonly attribute (DOMString or undefined) stack;
12661272
};
12671273
</pre>
12681274

12691275
An {{Exception}} value represents an exception.
12701276

12711277
<div algorithm>
12721278

1273-
To <dfn>create an Exception object</dfn> from a [=tag address=] |tagAddress| and [=list=]
1274-
of WebAssembly values |payload|, perform the following steps:
1279+
To <dfn>create an Exception object</dfn> from a [=tag address=] |tagAddress| and a [=list=] of
1280+
WebAssembly values |payload|, perform the following steps:
12751281

12761282
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
12771283
1. Let |types| be [=tag_parameters=](|store|, |tagAddress|).
@@ -1281,14 +1287,15 @@ of WebAssembly values |payload|, perform the following steps:
12811287
1. Let |exception| be a [=new=] {{Exception}}.
12821288
1. Set |exception|.\[[Type]] to |tagAddress|.
12831289
1. Set |exception|.\[[Payload]] to |payload|.
1290+
1. Set |exception|.\[[Stack]] to undefined.
12841291
1. Return |exception|.
12851292

12861293
</div>
12871294

12881295
<div algorithm>
12891296

12901297
The <dfn constructor for=Exception
1291-
lt="Exception(exceptionTag, payload)">new Exception(|exceptionTag|, |payload|)</dfn>
1298+
lt="Exception(exceptionTag, payload, options)">new Exception(|exceptionTag|, |payload|, |options|)</dfn>
12921299
constructor steps are:
12931300

12941301
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
@@ -1300,6 +1307,10 @@ constructor steps are:
13001307
1. [=list/Append=] ? [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmPayload|.
13011308
1. Set **this**.\[[Type]] to |exceptionTag|.\[[Address]].
13021309
1. Set **this**.\[[Payload]] to |wasmPayload|.
1310+
1. If |options|["traceStack"] is true,
1311+
1. Set **this**.\[[Stack]] to either a {{DOMString}} representation of the current call stack or undefined.
1312+
1. Otherwise,
1313+
1. Set **this**.\[[Stack]] to undefined.
13031314

13041315
</div>
13051316

@@ -1326,22 +1337,28 @@ The <dfn method for="Exception">is(|exceptionTag|)</dfn> method steps are:
13261337

13271338
</div>
13281339

1340+
<div algorithm>
1341+
1342+
The <dfn attribute for="Exception">stack</dfn> getter steps are:
1343+
1344+
1. Return **this**.\[[Stack]].
1345+
1346+
</div>
1347+
13291348
<h4 id="js-exceptions">JavaScript exceptions</h4>
13301349

13311350
The <dfn>JavaScript exception tag</dfn> is a [=tag address=] reserved by this
13321351
specification to distinguish exceptions originating from JavaScript.
13331352

13341353
For any [=associated store=] |store|, the result of
1335-
[=tag_parameters=](|store|, [=JavaScript exception tag=]) must be « [=externref=] ».
1336-
1337-
Issue: Should it be possible for `catch <JS-exception-tag>` to extract the payload from an exception with this tag?
1354+
[=tag_parameters=](|store|, [=JavaScript exception tag=]) must be « ».
13381355

13391356
<div algorithm>
13401357

1341-
To <dfn for=WebAssembly>throw</dfn> with a [=tag address=] |type| and matching [=list=] of WebAssembly values |payload|, perform the following steps:
1358+
To <dfn for=WebAssembly>throw</dfn> with a [=tag address=] |type|, a matching [=list=] of WebAssembly values |payload|, and an [=externref=] |opaqueData|, perform the following steps:
13421359

13431360
1. Unwind the stack until reaching the *catching try block* given |type|.
1344-
1. Invoke the catch block with |payload|.
1361+
1. Invoke the catch block with |payload| and |opaqueData|.
13451362

13461363
Note: This algorithm is expected to be moved into the core specification.
13471364

0 commit comments

Comments
 (0)