diff --git a/spec.html b/spec.html
index 5cfa730..4e60d8c 100644
--- a/spec.html
+++ b/spec.html
@@ -126,6 +126,17 @@
Agents
A map from the AsyncContext.Variable instances to the saved ECMAScript language value. Every Record in the List contains a unique [[AsyncContextKey]]. The map is initially empty.
+
+
+ [[ThrowAsyncContextMapping]]
+ |
+
+ ~unused~ or a List of Async Context Mapping Records
+ |
+
+ The value of [[AsyncContextMapping]] at the time of the last time an exception was thrown, if any. Used by hosts to provide Async Context Mapping information when reporting uncaught exceptions.
+ |
+
@@ -148,7 +159,7 @@
1. Perform ? HostCallJobCallback(_callback_, *undefined*, « _cell_.[[HeldValue]] »).
1. Let _previousContextMapping_ be AsyncContextSwap(_finalizationRegistry_.[[FinalizationRegistryAsyncContextSnapshot]]).
1. Let _result_ be Completion(HostCallJobCallback(_callback_, *undefined*, « _cell_.[[HeldValue]] »)).
- 1. AsyncContextSwap(_previousContextMapping_).
+ 1. AsyncContextSwap(_previousContextMapping_, _result_).
1. Perform ? _result_.
1. Return ~unused~.
@@ -203,6 +214,62 @@
+
+ ECMAScript Language: Statements and Declarations
+
+
+ The `try` Statement
+
+
+ Runtime Semantics: Evaluation
+ TryStatement : `try` Block Catch
+
+ 1. Let _B_ be Completion(Evaluation of |Block|).
+ 1. If _B_ is a throw completion, let _C_ be Completion(CatchClauseEvaluation of |Catch| with argument _B_.[[Value]]).
+ 1. Else, let _C_ be _B_.
+ 1. If _B_ is a throw completion, then
+ 1. Let _agentRecord_ be the surrounding agent's Agent Record.
+ 1. Set _agentRecord_.[[ThrowAsyncContextMapping]] to ~empty~.
+ 1. Let _C_ be Completion(CatchClauseEvaluation of |Catch| with argument _B_.[[Value]]).
+ 1. Else,
+ 1. Let _C_ be _B_.
+ 1. Return ? UpdateEmpty(_C_, *undefined*).
+
+ TryStatement : `try` Block Finally
+
+ 1. Let _agentRecord_ be the surrounding agent's AgentRecord.
+ 1. Let _B_ be Completion(Evaluation of |Block|).
+ 1. Let _throwAsyncContextMapping_ be _agentRecord_.[[ThrowAsyncContextMapping]].
+ 1. Let _F_ be Completion(Evaluation of |Finally|).
+ 1. If _F_ is a normal completion, set _F_ to _B_.
+ 1. If _F_ is a normal completion, then
+ 1. Set _agentRecord_.[[ThrowAsyncContextMapping]] to _throwAsyncContextMapping_.
+ 1. Set _F_ to _B_.
+ 1. Return ? UpdateEmpty(_F_, *undefined*).
+
+ TryStatement : `try` Block Catch Finally
+
+ 1. Let _agentRecord_ be the surrounding agent's Agent Record.
+ 1. Let _B_ be Completion(Evaluation of |Block|).
+ 1. If _B_ is a throw completion, let _C_ be Completion(CatchClauseEvaluation of |Catch| with argument _B_.[[Value]]).
+ 1. Else, let _C_ be _B_.
+ 1. If _B_ is a throw completion, then
+ 1. Set _agentRecord_.[[ThrowAsyncContextMapping]] to ~empty~.
+ 1. Let _C_ be Completion(CatchClauseEvaluation of |Catch| with argument _B_.[[Value]]).
+ 1. Else,
+ 1. Let _C_ be _B_.
+ 1. Let _throwAsyncContextMapping_ be _agentRecord_.[[ThrowAsyncContextMapping]].
+ 1. Let _F_ be Completion(Evaluation of |Finally|).
+ 1. If _F_ is a normal completion, set _F_ to _C_.
+ 1. If _F_ is a normal completion, then
+ 1. Set _agentRecord_.[[ThrowAsyncContextMapping]] to _throwAsyncContextMapping_.
+ 1. Set _F_ to _C_.
+ 1. Return ? UpdateEmpty(_F_, *undefined*).
+
+
+
+
+
ECMAScript Language: Functions and Classes
@@ -397,7 +464,7 @@
1. Else,
1. Return ? Call(_promiseCapability_.[[Resolve]], *undefined*, « _handlerResult_.[[Value]] »).
1. Let _resolvingFunctionResult_ be Completion(Call(_promiseCapability_.[[Resolve]], *undefined*, « _handlerResult_.[[Value]] »)).
- 1. AsyncContextSwap(_previousContextMapping_).
+ 1. AsyncContextSwap(_previousContextMapping_, _resolvingFunctionResult_).
1. Return _resolvingFunctionResult_.
1. Let _handlerRealm_ be *null*.
1. If _reaction_.[[Handler]] is not ~empty~, then
@@ -428,7 +495,7 @@
1. If _thenCallResult_ is an abrupt completion, then
1. Return ? Call(_resolvingFunctions_.[[Reject]], *undefined*, « _thenCallResult_.[[Value]] »).
1. Let _rejectResult_ be Completion(Call(_resolvingFunctions_.[[Reject]], *undefined*, « _thenCallResult_.[[Value]] »)).
- 1. AsyncContextSwap(_previousContextMapping_).
+ 1. AsyncContextSwap(_previousContextMapping_, _rejectResult_).
1. Return _rejectResult_.
1. AsyncContextSwap(_previousContextMapping_).
1. Return ? _thenCallResult_.
@@ -679,7 +746,7 @@
1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _methodContext_ is the currently running execution context.
1. If _previousContextMapping_ is not ~empty~, then
1. Assert: The result of AsyncContextSnapshot() is _generator_.[[GeneratorAsyncContextMapping]].
- 1. AsyncContextSwap(_previousContextMapping_).
+ 1. AsyncContextSwap(_previousContextMapping_, _result_).
1. Return ? _result_.
@@ -718,7 +785,7 @@
1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _methodContext_ is the currently running execution context.
1. If _previousContextMapping_ is not ~empty~, then
1. Assert: The result of AsyncContextSnapshot() is _generator_.[[GeneratorAsyncContextMapping]].
- 1. AsyncContextSwap(_previousContextMapping_).
+ 1. AsyncContextSwap(_previousContextMapping_, _result_).
1. Return ? _result_.
@@ -954,7 +1021,8 @@
AsyncContextSwap (
- _snapshotMapping_: a List of Async Context Mapping Records
+ _snapshotMapping_: a List of Async Context Mapping Records,
+ optional _completion_: a Completion Record,
): a List of Async Context Mapping Records
@@ -1212,7 +1284,7 @@ AsyncContext.Variable.prototype.run ( _value_, _func_, ..._args_ )
1. Append _p_ to _asyncContextMapping_.
1. AsyncContextSwap(_asyncContextMapping_).
1. Let _result_ be Completion(Call(_func_, *undefined*, _args_)).
- 1. AsyncContextSwap(_previousContextMapping_).
+ 1. AsyncContextSwap(_previousContextMapping_, _result_).
1. Return _result_.