From 2a2457646689497167159b7f78a4a2554cc4c66b Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 25 Aug 2022 17:48:02 +0200 Subject: [PATCH 1/3] [js-api] Add stack trace support. --- document/js-api/index.bs | 47 ++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 8aca631c..1a6bd4c4 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -1043,11 +1043,11 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [ 1. Note: The expectation is that [=func_invoke=] will be updated to return (|store|, val* | [=error=] | (exception |exntag| |payload|)). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by the WebAssembly error mapping. - 1. If |ret| is exception |exntag| |payload|, then + 1. If |ret| is exception |exntag| |payload| |opaqueData|, then 1. If |exntag| is the [=JavaScript exception tag=], then 1. Let « [=ref.extern=] |externaddr| » be |payload|. 1. Throw the result of [=retrieving an extern value=] from |externaddr|. - 1. Let |exception| be [=create an Exception object|a new Exception=] for |exntag| and |payload|. + 1. Let |exception| be [=create an Exception object|a new Exception=] for |exntag|, |payload| and |opaqueData|. 1. Throw |exception|. 1. Let |outArity| be the [=list/size=] of |ret|. 1. If |outArity| is 0, return undefined. @@ -1105,10 +1105,16 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not 1. If |v| [=implements=] {{Exception}}, 1. Let |type| be |v|.\[[Type]]. 1. Let |payload| be |v|.\[[Payload]]. + 1. If |v|.\[[Stack]] is undefined, + 1. Let |opaqueValue| be [=ref.null=] [=externref=]. + 1. Otherwise, + 1. Assert: [=Type=](|v|.\[[Stack]]) is String. + 1. Let |opaqueValue| be [=ToWebAssemblyValue=](|v|.\[[Stack]], [=externref=]) 1. Otherwise, 1. Let |type| be the [=JavaScript exception tag=]. 1. Let |payload| be [=ToWebAssemblyValue=](|v|, [=externref=]). - 1. [=WebAssembly/Throw=] with |type| and |payload|. + 1. Let |opaqueValue| be [=ref.null=] [=externref=]. + 1. [=WebAssembly/Throw=] with |type|, |payload| and |opaqueValue|. 1. Otherwise, return |result|.\[[Value]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|). @@ -1258,11 +1264,16 @@ Advisement: This method is only expected to be implemented or shipped when both

Runtime exceptions

+dictionary ExceptionOptions {
+  boolean traceStack = false;
+};
+
 [LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
 interface Exception {
-  constructor(Tag exceptionTag, sequence<any> payload);
+  constructor(Tag exceptionTag, sequence<any> payload, optional ExceptionOptions options = {});
   any getArg(Tag exceptionTag, unsigned long index);
   boolean is(Tag exceptionTag);
+  readonly attribute (DOMString or undefined) stack;
 };
 
@@ -1270,8 +1281,8 @@ An {{Exception}} value represents an exception.
-To create an Exception object from a [=tag address=] |tagAddress| and [=list=] -of WebAssembly values |payload|, perform the following steps: +To create an Exception object from a [=tag address=] |tagAddress|, [=list=] of +WebAssembly values |payload|, and [=externref=] |opaqueData|, perform the following steps: 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let |types| be [=tag_parameters=](|store|, |tagAddress|). @@ -1281,6 +1292,12 @@ of WebAssembly values |payload|, perform the following steps: 1. Let |exception| be a [=new=] {{Exception}}. 1. Set |exception|.\[[Type]] to |tagAddress|. 1. Set |exception|.\[[Payload]] to |payload|. +1. If |opaqueData| is [=ref.null=] [=externref=], + 1. Set |exception|.\[[Stack]] to undefined. +1. Otherwise, + 1. Let |stack| be the result of [=retrieving an extern value=] from |opaqueData|. + 1. Assert: [=Type=](|stack|) is String. + 1. Set |exception|.\[[Stack]] to |stack|. 1. Return |exception|.
@@ -1288,7 +1305,7 @@ of WebAssembly values |payload|, perform the following steps:
The new Exception(|exceptionTag|, |payload|) +lt="Exception(exceptionTag, payload, options)">new Exception(|exceptionTag|, |payload|, |options|) constructor steps are: 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. @@ -1300,6 +1317,10 @@ constructor steps are: 1. [=list/Append=] ? [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmPayload|. 1. Set **this**.\[[Type]] to |exceptionTag|.\[[Address]]. 1. Set **this**.\[[Payload]] to |wasmPayload|. +1. If |options|["traceStack"] is true, + 1. Set **this**.\[[Stack]] to either a {{DOMString}} representation of the current call stack or undefined. +1. Otherwise, + 1. Set **this**.\[[Stack]] to undefined.
@@ -1326,6 +1347,14 @@ The is(|exceptionTag|) method steps are: +
+ +The stack getter steps are: + +1. Return **this**.\[[Stack]]. + +
+

JavaScript exceptions

The JavaScript exception tag is a [=tag address=] reserved by this @@ -1338,10 +1367,10 @@ For any [=associated store=] |store|, the result of
-To throw with a [=tag address=] |type| and matching [=list=] of WebAssembly values |payload|, perform the following steps: +To throw with a [=tag address=] |type|, a matching [=list=] of WebAssembly values |payload|, and an [=externref=] |opaqueData|, perform the following steps: 1. Unwind the stack until reaching the *catching try block* given |type|. -1. Invoke the catch block with |payload|. +1. Invoke the catch block with |payload| and |opaqueData|. Note: This algorithm is expected to be moved into the core specification. From b15d6353380202fef6b14bb263294eb59fcdc0b4 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 16 Sep 2022 16:58:11 +0200 Subject: [PATCH 2/3] fixes --- document/js-api/index.bs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 1a6bd4c4..379e996e 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -1040,7 +1040,7 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [ 1. [=list/Append=] [=ToWebAssemblyValue=](|arg|, |t|) to |args|. 1. Set |i| to |i| + 1. 1. Let (|store|, |ret|) be the result of [=func_invoke=](|store|, |funcaddr|, |args|). - 1. Note: The expectation is that [=func_invoke=] will be updated to return (|store|, val* | [=error=] | (exception |exntag| |payload|)). + 1. Note: The expectation is that [=func_invoke=] will be updated to return (|store|, val* | [=error=] | (exception |exntag| |payload| |opaqueData|)). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by the WebAssembly error mapping. 1. If |ret| is exception |exntag| |payload| |opaqueData|, then @@ -1106,15 +1106,15 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not 1. Let |type| be |v|.\[[Type]]. 1. Let |payload| be |v|.\[[Payload]]. 1. If |v|.\[[Stack]] is undefined, - 1. Let |opaqueValue| be [=ref.null=] [=externref=]. + 1. Let |opaqueData| be [=ref.null=] [=externref=]. 1. Otherwise, 1. Assert: [=Type=](|v|.\[[Stack]]) is String. - 1. Let |opaqueValue| be [=ToWebAssemblyValue=](|v|.\[[Stack]], [=externref=]) + 1. Let |opaqueData| be [=ToWebAssemblyValue=](|v|.\[[Stack]], [=externref=]) 1. Otherwise, 1. Let |type| be the [=JavaScript exception tag=]. 1. Let |payload| be [=ToWebAssemblyValue=](|v|, [=externref=]). - 1. Let |opaqueValue| be [=ref.null=] [=externref=]. - 1. [=WebAssembly/Throw=] with |type|, |payload| and |opaqueValue|. + 1. Let |opaqueData| be [=ref.null=] [=externref=]. + 1. [=WebAssembly/Throw=] with |type|, |payload| and |opaqueData|. 1. Otherwise, return |result|.\[[Value]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|). From 8018474f1f9e874e27b256cf88bf77516122bdea Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 20 Sep 2022 11:50:51 +0200 Subject: [PATCH 3/3] Rework. --- document/js-api/index.bs | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 379e996e..bf37b1fe 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -1044,10 +1044,10 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [ 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by the WebAssembly error mapping. 1. If |ret| is exception |exntag| |payload| |opaqueData|, then - 1. If |exntag| is the [=JavaScript exception tag=], then - 1. Let « [=ref.extern=] |externaddr| » be |payload|. + 1. If |opaqueData| is not [=ref.null=] [=externref=], + 1. Let « [=ref.extern=] |externaddr| » be |opaqueData|. 1. Throw the result of [=retrieving an extern value=] from |externaddr|. - 1. Let |exception| be [=create an Exception object|a new Exception=] for |exntag|, |payload| and |opaqueData|. + 1. Let |exception| be [=create an Exception object|a new Exception=] for |exntag| and |payload|. 1. Throw |exception|. 1. Let |outArity| be the [=list/size=] of |ret|. 1. If |outArity| is 0, return undefined. @@ -1105,15 +1105,10 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not 1. If |v| [=implements=] {{Exception}}, 1. Let |type| be |v|.\[[Type]]. 1. Let |payload| be |v|.\[[Payload]]. - 1. If |v|.\[[Stack]] is undefined, - 1. Let |opaqueData| be [=ref.null=] [=externref=]. - 1. Otherwise, - 1. Assert: [=Type=](|v|.\[[Stack]]) is String. - 1. Let |opaqueData| be [=ToWebAssemblyValue=](|v|.\[[Stack]], [=externref=]) 1. Otherwise, 1. Let |type| be the [=JavaScript exception tag=]. - 1. Let |payload| be [=ToWebAssemblyValue=](|v|, [=externref=]). - 1. Let |opaqueData| be [=ref.null=] [=externref=]. + 1. Let |payload| be « ». + 1. Let |opaqueData| be [=ToWebAssemblyValue=](|v|, [=externref=]) 1. [=WebAssembly/Throw=] with |type|, |payload| and |opaqueData|. 1. Otherwise, return |result|.\[[Value]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. @@ -1281,8 +1276,8 @@ An {{Exception}} value represents an exception.
-To create an Exception object from a [=tag address=] |tagAddress|, [=list=] of -WebAssembly values |payload|, and [=externref=] |opaqueData|, perform the following steps: +To create an Exception object from a [=tag address=] |tagAddress| and a [=list=] of +WebAssembly values |payload|, perform the following steps: 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let |types| be [=tag_parameters=](|store|, |tagAddress|). @@ -1292,12 +1287,7 @@ WebAssembly values |payload|, and [=externref=] |opaqueData|, perform the follow 1. Let |exception| be a [=new=] {{Exception}}. 1. Set |exception|.\[[Type]] to |tagAddress|. 1. Set |exception|.\[[Payload]] to |payload|. -1. If |opaqueData| is [=ref.null=] [=externref=], - 1. Set |exception|.\[[Stack]] to undefined. -1. Otherwise, - 1. Let |stack| be the result of [=retrieving an extern value=] from |opaqueData|. - 1. Assert: [=Type=](|stack|) is String. - 1. Set |exception|.\[[Stack]] to |stack|. +1. Set |exception|.\[[Stack]] to undefined. 1. Return |exception|.
@@ -1361,9 +1351,7 @@ The JavaScript exception tag is a [=tag address=] reserved by this specification to distinguish exceptions originating from JavaScript. For any [=associated store=] |store|, the result of -[=tag_parameters=](|store|, [=JavaScript exception tag=]) must be « [=externref=] ». - - Issue: Should it be possible for `catch ` to extract the payload from an exception with this tag? +[=tag_parameters=](|store|, [=JavaScript exception tag=]) must be « ».