From b5349abb31a7dbbaee74043f56d26192764250c0 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 3 Feb 2022 23:36:10 -0800 Subject: [PATCH 1/4] Update explainer on stack trace support in JS API This updates the explainer on - We add stack trace option to `Exception` class in the JS API - `Exception` can contain an optional `externref` to carry a stack trace - `Exception` is not a subclass of JS `Error` The WebIDL syntax is suggested by @eqrion in https://github.com/WebAssembly/exception-handling/issues/183#issuecomment-998899547 and https://github.com/WebAssembly/exception-handling/issues/183#issuecomment-1003178801. Addresses #183 and #189. --- proposals/exception-handling/Exceptions.md | 30 ++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/proposals/exception-handling/Exceptions.md b/proposals/exception-handling/Exceptions.md index c0120fca..fed248d9 100644 --- a/proposals/exception-handling/Exceptions.md +++ b/proposals/exception-handling/Exceptions.md @@ -394,13 +394,6 @@ within `()` after `delegate`s are the label operands in immediate values. ### JS API -#### Stack traces - -When an exception is thrown, the runtime will pop the stack across function -calls until a corresponding, enclosing try block is found. Some runtimes, -especially web VMs may also associate a stack trace that can be used to report -uncaught exceptions. However, the details of this are left to the embedder. - #### Traps The `catch`/`catch_all` instruction catches exceptions generated by the `throw` @@ -455,6 +448,21 @@ access to the data fields of a `Exception` if a matching tag is given. This last check ensures that without access to a WebAssembly module's exported exception tag, the associated data fields cannot be read. +The `Exception` constructor can take an optional `ExceptionOptions` argument, +which can optionally contain `traceStack` entry. When `traceStack` is `true`, +web VMs can attach a stack trace string to `Exception.stack` field, as in +JavaScript's `Error` class. While `Exception` is not a subclass of JavaScript's +`Error` and it can be used to represent normal control flow constructs, +`traceStack` field can be set when we use it to represent errors. The format of +stack trace strings conform to the [WebAssembly stack trace +conventions](https://webassembly.github.io/spec/web-api/index.html#conventions). +When `ExceptionOption` is not provided or it does not contain `traceStack` +entry, `traceStack` is considered `false` by default. + +To preserve stack trace info when crossing the JS to Wasm boundary, `Exception` +can internally contain an optional `externref` value containing a stack trace +string, which is propagated when caught by `catch` and rethrown by `rethrow`. + More formally, the added interfaces look like the following: ```WebIDL @@ -464,11 +472,17 @@ interface Tag { TagType type(); }; +[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] +dictionary ExceptionOptions { + optional boolean traceStack; +}; + [LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] interface Exception { - constructor(Tag tag, sequence payload); + constructor(Tag tag, sequence payload, optional ExceptionOptions options); any getArg(Tag tag, unsigned long index); boolean is(Tag tag); + readonly attribute (DOMString or undefined) stack; }; ``` From 57f65ee2b83668abcff3e213b1d08d9d9615909c Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 9 Feb 2022 18:37:02 -0800 Subject: [PATCH 2/4] Move `TagType` info pseudocode for consistency --- proposals/exception-handling/Exceptions.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/proposals/exception-handling/Exceptions.md b/proposals/exception-handling/Exceptions.md index fed248d9..7c3e393d 100644 --- a/proposals/exception-handling/Exceptions.md +++ b/proposals/exception-handling/Exceptions.md @@ -467,6 +467,10 @@ More formally, the added interfaces look like the following: ```WebIDL [LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] +dictionary TagType { + required sequence parameters; +}; + interface Tag { constructor(TagType type); TagType type(); @@ -486,10 +490,10 @@ interface Exception { }; ``` -Where `type TagType = {parameters: ValueType[]}`, following the format of the -type reflection proposal (`TagType` corresponds to a `FunctionType` without a -`results` property). `TagType` could be extended in the future for other -proposals that require a richer type specification. +`TagType` corresponds to a `FunctionType` in [the type reflection +proposal](https://github.com/WebAssembly/js-types/blob/main/proposals/js-types/Overview.md), +without a `results` property). `TagType` could be extended in the future for +other proposals that require a richer type specification. ## Changes to the text format From fe4fca11321486ea2f23206a80cc256ef0262add Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 9 Feb 2022 18:41:41 -0800 Subject: [PATCH 3/4] Attach `Exposed` only to interfaces --- proposals/exception-handling/Exceptions.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/exception-handling/Exceptions.md b/proposals/exception-handling/Exceptions.md index 7c3e393d..1f35829b 100644 --- a/proposals/exception-handling/Exceptions.md +++ b/proposals/exception-handling/Exceptions.md @@ -466,17 +466,16 @@ string, which is propagated when caught by `catch` and rethrown by `rethrow`. More formally, the added interfaces look like the following: ```WebIDL -[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] dictionary TagType { required sequence parameters; }; +[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] interface Tag { constructor(TagType type); TagType type(); }; -[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] dictionary ExceptionOptions { optional boolean traceStack; }; From ba632716559701cd5fb715718643fff9861216fa Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 9 Feb 2022 22:55:59 -0800 Subject: [PATCH 4/4] dictionary entities are by default optional --- proposals/exception-handling/Exceptions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/exception-handling/Exceptions.md b/proposals/exception-handling/Exceptions.md index 1f35829b..42701ed2 100644 --- a/proposals/exception-handling/Exceptions.md +++ b/proposals/exception-handling/Exceptions.md @@ -477,7 +477,7 @@ interface Tag { }; dictionary ExceptionOptions { - optional boolean traceStack; + boolean traceStack = false; }; [LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]