diff --git a/proposals/exception-handling/Exceptions.md b/proposals/exception-handling/Exceptions.md index c0120fca..42701ed2 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,27 +448,51 @@ 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 +dictionary TagType { + required sequence parameters; +}; + [LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] interface Tag { constructor(TagType type); TagType type(); }; +dictionary ExceptionOptions { + boolean traceStack = false; +}; + [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; }; ``` -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