diff --git a/esmeta-ignore.json b/esmeta-ignore.json
index dcb6101596..8241776955 100644
--- a/esmeta-ignore.json
+++ b/esmeta-ignore.json
@@ -1,4 +1,5 @@
[
+ "AddDisposableResource",
"AddEntriesFromIterable",
"ArrayAssignmentPattern[0,0].DestructuringAssignmentEvaluation",
"ArrayAssignmentPattern[0,1].DestructuringAssignmentEvaluation",
@@ -19,6 +20,7 @@
"CreateBuiltinFunction",
"CreateMappedArgumentsObject",
"CreateSharedByteDataBlock",
+ "DeclarativeEnvironmentRecord.InitializeBinding",
"ForIn/OfBodyEvaluation",
"FunctionBody[0,0].EvaluateFunctionBody",
"GeneratorBody[0,0].EvaluateGeneratorBody",
@@ -26,11 +28,13 @@
"GetMethod",
"GetPromiseResolve",
"GetThisValue",
+ "GlobalEnvironmentRecord.InitializeBinding",
"InnerModuleEvaluation",
"LabelledItem[1,0].LabelledEvaluation",
"LengthOfArrayLike",
"MethodDefinition[0,0].DefineMethod",
"ModuleNamespaceCreate",
+ "ObjectEnvironmentRecord.InitializeBinding",
"OrdinaryFunctionCreate",
"ProxyCreate",
"ScriptEvaluation",
diff --git a/spec.html b/spec.html
index b53a6a0c3b..48e64000bb 100644
--- a/spec.html
+++ b/spec.html
@@ -1221,6 +1221,17 @@
Well-Known Symbols
Value and Purpose
+
+
+ @@asyncDispose
+ |
+
+ `"Symbol.asyncDispose"`
+ |
+
+ A method that performs explicit resource cleanup on an object. Called by the semantics of the `await using` declaration and AsyncDisposableStack objects.
+ |
+
@@asyncIterator
@@ -1232,6 +1243,17 @@ Well-Known Symbols
A method that returns the default AsyncIterator for an object. Called by the semantics of the `for`-`await`-`of` statement.
|
+
+
+ @@dispose
+ |
+
+ `"Symbol.dispose"`
+ |
+
+ A method that performs explicit resource cleanup on an object. Called by the semantics of the `using` declaration and DisposableStack objects.
+ |
+
@@hasInstance
@@ -3288,6 +3310,17 @@ Well-Known Intrinsic Objects
The prototype of Array iterator objects ()
|
+
+
+ %AsyncDisposableStack%
+ |
+
+ `AsyncDisposableStack`
+ |
+
+ The AsyncDisposableStack constructor ()
+ |
+
%AsyncFromSyncIteratorPrototype%
@@ -3437,6 +3470,17 @@ Well-Known Intrinsic Objects
The `decodeURIComponent` function ()
|
+
+
+ %DisposableStack%
+ |
+
+ `DisposableStack`
+ |
+
+ The DisposableStack constructor ()
+ |
+
%encodeURI%
@@ -3847,6 +3891,17 @@ Well-Known Intrinsic Objects
The prototype of String iterator objects ()
|
+
+
+ %SuppressedError%
+ |
+
+ `SuppressedError`
+ |
+
+ The `SuppressedError` constructor ()
+ |
+
%Symbol%
@@ -4328,6 +4383,7 @@
InitializeReferencedBinding (
_V_: a Reference Record,
_W_: an ECMAScript language value,
+ _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~,
): either a normal completion containing ~unused~ or an abrupt completion
|
- InitializeBinding(N, V)
+ InitializeBinding(N, V, _hint_)
|
- Set the value of an already existing but uninitialized binding in an Environment Record. The String value _N_ is the text of the bound name. _V_ is the value for the binding and is a value of any ECMAScript language type.
+ Set the value of an already existing but uninitialized binding in an Environment Record. The String value _N_ is the text of the bound name. _V_ is the value for the binding and is a value of any ECMAScript language type. _hint_ indicates whether the binding came from either a `using` declaration (~sync-dispose~), an `await using` declaration (~async-dispose~), or a regular variable declaration (~normal~).
|
@@ -10035,6 +10498,7 @@ The Environment Record Type Hierarchy
Declarative Environment Records
Each Declarative Environment Record is associated with an ECMAScript program scope containing variable, constant, let, class, module, import, and/or function declarations. A Declarative Environment Record binds the set of identifiers defined by the declarations contained within its scope.
+ Every declarative Environment Record also has a [[DisposeCapability]] field, which contains a DisposeCapability Record. This field holds a stack of resources tracked by the `using` declarations and `await using` declarations that must be disposed when the Evaluation step that constructed the Environment Record has completed.
The behaviour of the concrete specification methods for Declarative Environment Records is defined by the following algorithms.
@@ -10103,7 +10567,8 @@
InitializeBinding (
_N_: a String,
_V_: an ECMAScript language value,
- ): a normal completion containing ~unused~
+ _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~,
+ ): either a normal completion containing ~unused~ or a throw completion
1. Assert: _envRec_ must have an uninitialized binding for _N_.
+ 1. If _hint_ is not ~normal~, perform ? AddDisposableResource(_envRec_.[[DisposeCapability]], _V_, _hint_).
1. Set the bound value for _N_ in _envRec_ to _V_.
1. Record that the binding for _N_ in _envRec_ has been initialized.
1. Return ~unused~.
@@ -10139,7 +10605,7 @@
1. [id="step-setmutablebinding-missing-binding"] If _envRec_ does not have a binding for _N_, then
1. If _S_ is *true*, throw a *ReferenceError* exception.
1. Perform ! _envRec_.CreateMutableBinding(_N_, *true*).
- 1. Perform ! _envRec_.InitializeBinding(_N_, _V_).
+ 1. Perform ! _envRec_.InitializeBinding(_N_, _V_, ~normal~).
1. Return ~unused~.
1. If the binding for _N_ in _envRec_ is a strict binding, set _S_ to *true*.
1. If the binding for _N_ in _envRec_ has not yet been initialized, then
@@ -10343,6 +10809,7 @@
InitializeBinding (
_N_: a String,
_V_: an ECMAScript language value,
+ _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~,
): either a normal completion containing ~unused~ or a throw completion
+ 1. Assert: _hint_ is ~normal~.
1. Perform ? _envRec_.SetMutableBinding(_N_, _V_, *false*).
1. Return ~unused~.
@@ -10851,6 +11319,7 @@
InitializeBinding (
_N_: a String,
_V_: an ECMAScript language value,
+ _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~,
): either a normal completion containing ~unused~ or a throw completion
@@ -11128,7 +11598,7 @@
1. Let _extensible_ be ? IsExtensible(_globalObject_).
1. If _hasProperty_ is *false* and _extensible_ is *true*, then
1. Perform ? _ObjRec_.CreateMutableBinding(_N_, _D_).
- 1. Perform ? _ObjRec_.InitializeBinding(_N_, *undefined*).
+ 1. Perform ? _ObjRec_.InitializeBinding(_N_, *undefined*, ~normal~).
1. If _envRec_.[[VarNames]] does not contain _N_, then
1. Append _N_ to _envRec_.[[VarNames]].
1. Return ~unused~.
@@ -11329,6 +11799,7 @@
1. Let _env_ be a new Declarative Environment Record containing no bindings.
1. Set _env_.[[OuterEnv]] to _E_.
+ 1. Set _env_.[[DisposeCapability]] to NewDisposeCapability().
1. Return _env_.
@@ -11368,6 +11839,7 @@
1. Else, set _env_.[[ThisBindingStatus]] to ~uninitialized~.
1. Set _env_.[[NewTarget]] to _newTarget_.
1. Set _env_.[[OuterEnv]] to _F_.[[Environment]].
+ 1. Set _env_.[[DisposeCapability]] to NewDisposeCapability().
1. Return _env_.
@@ -11405,6 +11877,7 @@
1. Let _env_ be a new Module Environment Record containing no bindings.
1. Set _env_.[[OuterEnv]] to _E_.
+ 1. Set _env_.[[DisposeCapability]] to NewDisposeCapability().
1. Return _env_.
@@ -13670,7 +14143,7 @@
1. If _alreadyDeclared_ is *false*, then
1. Perform ! _env_.CreateMutableBinding(_paramName_, *false*).
1. If _hasDuplicates_ is *true*, then
- 1. Perform ! _env_.InitializeBinding(_paramName_, *undefined*).
+ 1. Perform ! _env_.InitializeBinding(_paramName_, *undefined*, ~normal~).
1. If _argumentsObjectNeeded_ is *true*, then
1. If _strict_ is *true* or _simpleParameterList_ is *false*, then
1. Let _ao_ be CreateUnmappedArgumentsObject(_argumentsList_).
@@ -13682,7 +14155,7 @@
1. NOTE: In strict mode code early errors prevent attempting to assign to this binding, so its mutability is not observable.
1. Else,
1. Perform ! _env_.CreateMutableBinding(*"arguments"*, *false*).
- 1. Perform ! _env_.InitializeBinding(*"arguments"*, _ao_).
+ 1. Perform ! _env_.InitializeBinding(*"arguments"*, _ao_, ~normal~).
1. Let _parameterBindings_ be the list-concatenation of _parameterNames_ and « *"arguments"* ».
1. Else,
1. Let _parameterBindings_ be _parameterNames_.
@@ -13698,7 +14171,7 @@
1. If _instantiatedVarNames_ does not contain _n_, then
1. Append _n_ to _instantiatedVarNames_.
1. Perform ! _env_.CreateMutableBinding(_n_, *false*).
- 1. Perform ! _env_.InitializeBinding(_n_, *undefined*).
+ 1. Perform ! _env_.InitializeBinding(_n_, *undefined*, ~normal~).
1. Let _varEnv_ be _env_.
1. Else,
1. NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body.
@@ -13713,7 +14186,7 @@
1. Let _initialValue_ be *undefined*.
1. Else,
1. Let _initialValue_ be ! _env_.GetBindingValue(_n_, *false*).
- 1. Perform ! _varEnv_.InitializeBinding(_n_, _initialValue_).
+ 1. Perform ! _varEnv_.InitializeBinding(_n_, _initialValue_, ~normal~).
1. NOTE: A var with the same name as a formal parameter initially has the same value as the corresponding initialized parameter.
1. [id="step-functiondeclarationinstantiation-web-compat-insertion-point"] NOTE: Annex adds additional steps at this point.
1. If _strict_ is *false*, then
@@ -16597,7 +17070,7 @@ Static Semantics: IdentifierCodePoint ( ): a code point
Keywords and Reserved Words
A keyword is a token that matches |IdentifierName|, but also has a syntactic use; that is, it appears literally, in a `fixed width` font, in some syntactic production. The keywords of ECMAScript include `if`, `while`, `async`, `await`, and many others.
A reserved word is an |IdentifierName| that cannot be used as an identifier. Many keywords are reserved words, but some are not, and some are reserved only in certain contexts. `if` and `while` are reserved words. `await` is reserved only inside async functions and modules. `async` is not reserved; it can be used as a variable name or statement label without restriction.
- This specification uses a combination of grammatical productions and early error rules to specify which names are valid identifiers and which are reserved words. All tokens in the |ReservedWord| list below, except for `await` and `yield`, are unconditionally reserved. Exceptions for `await` and `yield` are specified in , using parameterized syntactic productions. Lastly, several early error rules restrict the set of valid identifiers. See , , , and . In summary, there are five categories of identifier names:
+ This specification uses a combination of grammatical productions and early error rules to specify which names are valid identifiers and which are reserved words. All tokens in the |ReservedWord| list below, except for `await` and `yield`, are unconditionally reserved. Exceptions for `await` and `yield` are specified in , using parameterized syntactic productions. Lastly, several early error rules restrict the set of valid identifiers. See , , , and . In summary, there are five categories of identifier names:
-
Those that are always allowed as identifiers, and are not keywords, such as `Math`, `window`, `toString`, and `_`;
@@ -17722,6 +18195,9 @@ Rules of Automatic Semicolon Insertion
LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] `++`
LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] `--`
+ UsingDeclaration[In, Yield, Await] :
+ `using` [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] `;`
+
ContinueStatement[Yield, Await] :
`continue` `;`
`continue` [no LineTerminator here] LabelIdentifier[?Yield, ?Await] `;`
@@ -17777,6 +18253,9 @@ Rules of Automatic Semicolon Insertion
-
When a `++` or `--` token is encountered where the parser would treat it as a postfix operator, and at least one |LineTerminator| occurred between the preceding token and the `++` or `--` token, then a semicolon is automatically inserted before the `++` or `--` token.
+ -
+ When a `using` token is encountered and a |LineTerminator| is encountered before an |IdentifierName| token, a semicolon is automatically inserted after the `using` token.
+
-
When a `continue`, `break`, `return`, `throw`, or `yield` token is encountered and a |LineTerminator| is encountered before the next token, a semicolon is automatically inserted after the `continue`, `break`, `return`, `throw`, or `yield` token.
@@ -17795,6 +18274,9 @@ Rules of Automatic Semicolon Insertion
-
A postfix `++` or `--` operator should be on the same line as its operand.
+ -
+ A |BindingList| in a `using` declaration should start on the same line as the `using` token.
+
-
An |Expression| in a `return` or `throw` statement or an |AssignmentExpression| in a `yield` expression should start on the same line as the `return`, `throw`, or `yield` token.
@@ -19761,7 +20243,21 @@ Syntax
`-` UnaryExpression[?Yield, ?Await]
`~` UnaryExpression[?Yield, ?Await]
`!` UnaryExpression[?Yield, ?Await]
- [+Await] AwaitExpression[?Yield]
+ [+Await] CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] #awaitusingcover
+
+ CoverAwaitExpressionAndAwaitUsingDeclarationHead[Yield] :
+ `await` UnaryExpression[?Yield, +Await]
+
+
+ Supplemental Syntax
+
+ When processing an instance of the production
+ UnaryExpression : CoverAwaitExpressionAndAwaitUsingDeclarationHead
+ the interpretation of |CoverAwaitExpressionAndAwaitUsingDeclarationHead| is refined using the following grammar:
+
+
+ AwaitExpression[Yield] :
+ `await` UnaryExpression[?Yield, +Await]
@@ -21104,6 +21600,7 @@ Runtime Semantics: Evaluation
1. Perform BlockDeclarationInstantiation(|StatementList|, _blockEnv_).
1. Set the running execution context's LexicalEnvironment to _blockEnv_.
1. Let _blockValue_ be Completion(Evaluation of |StatementList|).
+ 1. Set _blockValue_ to Completion(DisposeResources(_blockEnv_.[[DisposeCapability]], _blockValue_)).
1. Set the running execution context's LexicalEnvironment to _oldEnv_.
1. Return ? _blockValue_.
@@ -21158,7 +21655,7 @@
1. If _d_ is either a |FunctionDeclaration|, a |GeneratorDeclaration|, an |AsyncFunctionDeclaration|, or an |AsyncGeneratorDeclaration|, then
1. Let _fn_ be the sole element of the BoundNames of _d_.
1. Let _fo_ be InstantiateFunctionObject of _d_ with arguments _env_ and _privateEnv_.
- 1. [id="step-blockdeclarationinstantiation-initializebinding"] Perform ! _env_.InitializeBinding(_fn_, _fo_). NOTE: This step is replaced in section .
+ 1. [id="step-blockdeclarationinstantiation-initializebinding"] Perform ! _env_.InitializeBinding(_fn_, _fo_, ~normal~). NOTE: This step is replaced in section .
1. Return ~unused~.
@@ -21167,30 +21664,49 @@
Declarations and the Variable Statement
-
- Let and Const Declarations
+
+ Let, Const, Using, and Await Using Declarations
- `let` and `const` declarations define variables that are scoped to the running execution context's LexicalEnvironment. The variables are created when their containing Environment Record is instantiated but may not be accessed in any way until the variable's |LexicalBinding| is evaluated. A variable defined by a |LexicalBinding| with an |Initializer| is assigned the value of its |Initializer|'s |AssignmentExpression| when the |LexicalBinding| is evaluated, not when the variable is created. If a |LexicalBinding| in a `let` declaration does not have an |Initializer| the variable is assigned the value *undefined* when the |LexicalBinding| is evaluated.
+ `let`, `const`, `using`, and `await using` declarations define variables that are scoped to the running execution context's LexicalEnvironment. The variables are created when their containing Environment Record is instantiated but may not be accessed in any way until the variable's |LexicalBinding| is evaluated. A variable defined by a |LexicalBinding| with an |Initializer| is assigned the value of its |Initializer|'s |AssignmentExpression| when the |LexicalBinding| is evaluated, not when the variable is created. If a |LexicalBinding| in a `let` declaration does not have an |Initializer| the variable is assigned the value *undefined* when the |LexicalBinding| is evaluated.
Syntax
LexicalDeclaration[In, Yield, Await] :
- LetOrConst BindingList[?In, ?Yield, ?Await] `;`
+ LetOrConst BindingList[?In, ?Yield, ?Await, +Pattern] `;`
+ UsingDeclaration[?In, ?Yield, ?Await]
+ [+Await] AwaitUsingDeclaration[?In, ?Yield]
LetOrConst :
`let`
`const`
- BindingList[In, Yield, Await] :
- LexicalBinding[?In, ?Yield, ?Await]
- BindingList[?In, ?Yield, ?Await] `,` LexicalBinding[?In, ?Yield, ?Await]
+ UsingDeclaration[In, Yield, Await] :
+ `using` [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] `;`
+
+ AwaitUsingDeclaration[In, Yield] :
+ CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] `;`
- LexicalBinding[In, Yield, Await] :
+ BindingList[In, Yield, Await, Pattern] :
+ LexicalBinding[?In, ?Yield, ?Await, ?Pattern]
+ BindingList[?In, ?Yield, ?Await, ?Pattern] `,` LexicalBinding[?In, ?Yield, ?Await, ?Pattern]
+
+ LexicalBinding[In, Yield, Await, Pattern] :
BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]?
- BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
+ [+Pattern] BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
-
+ Supplemental Syntax
+
+ When processing an instance of the production
+ AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;`
+ the interpretation of |CoverAwaitExpressionAndAwaitUsingDeclarationHead| is refined using the following grammar:
+
+
+ AwaitUsingDeclarationHead :
+ `await` [no LineTerminator here] `using`
+
+
+
Static Semantics: Early Errors
LexicalDeclaration : LetOrConst BindingList `;`
@@ -21201,6 +21717,37 @@ Static Semantics: Early Errors
It is a Syntax Error if the BoundNames of |BindingList| contains any duplicate entries.
+
+ UsingDeclaration :
+ `using` BindingList `;`
+
+
+ -
+ It is a Syntax Error if the BoundNames of |BindingList| contains *"let"*.
+
+ -
+ It is a Syntax Error if the BoundNames of |BindingList| contains any duplicate entries.
+
+ -
+ It is a Syntax Error if the goal symbol is |Script| and |UsingDeclaration| is not contained, either directly or indirectly, within a |Block|, |CaseBlock|, |ForStatement|, |ForInOfStatement|, |FunctionBody|, |GeneratorBody|, |AsyncGeneratorBody|, |AsyncFunctionBody|, or |ClassStaticBlockBody|.
+
+
+
+ AwaitUsingDeclaration :
+ CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;`
+
+
+ - |CoverAwaitExpressionAndAwaitUsingDeclarationHead| must cover an |AwaitUsingDeclarationHead|.
+ -
+ It is a Syntax Error if the BoundNames of |BindingList| contains *"let"*.
+
+ -
+ It is a Syntax Error if the BoundNames of |BindingList| contains any duplicate entries.
+
+ -
+ It is a Syntax Error if the goal symbol is |Script| and |AwaitUsingDeclaration| is not contained, either directly or indirectly, within a |Block|, |CaseBlock|, |ForStatement|, |ForInOfStatement|, |FunctionBody|, |GeneratorBody|, |AsyncGeneratorBody|, |AsyncFunctionBody|, or |ClassStaticBlockBody|.
+
+
LexicalBinding : BindingIdentifier Initializer?
-
@@ -21209,26 +21756,47 @@
Static Semantics: Early Errors
-
+
Runtime Semantics: Evaluation
LexicalDeclaration : LetOrConst BindingList `;`
- 1. Perform ? Evaluation of |BindingList|.
+ 1. Perform ? BindingEvaluation of |BindingList| with argument ~normal~.
+ 1. Return ~empty~.
+
+ UsingDeclaration : `using` BindingList `;`
+
+ 1. Perform ? BindingEvaluation of |BindingList| with argument ~sync-dispose~.
+ 1. Return ~empty~.
+
+ AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;`
+
+ 1. Perform ? BindingEvaluation of |BindingList| with argument ~async-dispose~.
1. Return ~empty~.
+
+
+
+
+ Runtime Semantics: BindingEvaluation (
+ _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~,
+ ): either a normal completion containing ~unused~ or an abrupt completion
+
+
BindingList : BindingList `,` LexicalBinding
- 1. Perform ? Evaluation of |BindingList|.
- 1. Return ? Evaluation of |LexicalBinding|.
+ 1. Perform ? BindingEvaluation of |BindingList| with argument _hint_.
+ 1. Return ? BindingEvaluation of |LexicalBinding| with argument _hint_.
LexicalBinding : BindingIdentifier
+ 1. Assert: _hint_ is ~normal~.
1. Let _lhs_ be ! ResolveBinding(StringValue of |BindingIdentifier|).
- 1. Perform ! InitializeReferencedBinding(_lhs_, *undefined*).
- 1. Return ~empty~.
+ 1. Perform ! InitializeReferencedBinding(_lhs_, *undefined*, ~normal~).
+ 1. Return ~unused~.
- A static semantics rule ensures that this form of |LexicalBinding| never occurs in a `const` declaration.
+ A static semantics rule ensures that this form of |LexicalBinding| never occurs in a `const`, `using`, or `await using` declaration.
LexicalBinding : BindingIdentifier Initializer
@@ -21239,11 +21807,12 @@ Runtime Semantics: Evaluation
1. Else,
1. Let _rhs_ be ? Evaluation of |Initializer|.
1. Let _value_ be ? GetValue(_rhs_).
- 1. Perform ! InitializeReferencedBinding(_lhs_, _value_).
- 1. Return ~empty~.
+ 1. Perform ? InitializeReferencedBinding(_lhs_, _value_, _hint_).
+ 1. Return ~unused~.
LexicalBinding : BindingPattern Initializer
+ 1. Assert: _hint_ is ~normal~.
1. Let _rhs_ be ? Evaluation of |Initializer|.
1. Let _value_ be ? GetValue(_rhs_).
1. Let _env_ be the running execution context's LexicalEnvironment.
@@ -21409,7 +21978,7 @@
1. Let _restObj_ be OrdinaryObjectCreate(%Object.prototype%).
1. Perform ? CopyDataProperties(_restObj_, _value_, _excludedNames_).
1. If _environment_ is *undefined*, return ? PutValue(_lhs_, _restObj_).
- 1. Return ? InitializeReferencedBinding(_lhs_, _restObj_).
+ 1. Return ? InitializeReferencedBinding(_lhs_, _restObj_, ~normal~).
@@ -21446,7 +22015,7 @@
1. Let _defaultValue_ be ? Evaluation of |Initializer|.
1. Set _v_ to ? GetValue(_defaultValue_).
1. If _environment_ is *undefined*, return ? PutValue(_lhs_, _v_).
- 1. Return ? InitializeReferencedBinding(_lhs_, _v_).
+ 1. Return ? InitializeReferencedBinding(_lhs_, _v_, ~normal~).
@@ -21767,12 +22336,16 @@
1. Set the running execution context's LexicalEnvironment to _loopEnv_.
1. Let _forDcl_ be Completion(Evaluation of |LexicalDeclaration|).
1. If _forDcl_ is an abrupt completion, then
+ 1. Set _forDcl_ to Completion(DisposeResources(_loopEnv_.[[DisposeCapability]], _forDcl_)).
+ 1. Assert: _forDcl_ is an abrupt completion.
1. Set the running execution context's LexicalEnvironment to _oldEnv_.
1. Return ? _forDcl_.
1. If _isConst_ is *false*, let _perIterationLets_ be _boundNames_; otherwise let _perIterationLets_ be a new empty List.
1. If the first |Expression| is present, let _test_ be the first |Expression|; otherwise, let _test_ be ~empty~.
1. If the second |Expression| is present, let _increment_ be the second |Expression|; otherwise, let _increment_ be ~empty~.
1. Let _bodyResult_ be Completion(ForBodyEvaluation(_test_, _increment_, |Statement|, _perIterationLets_, _labelSet_)).
+ 1. Set _bodyResult_ to Completion(DisposeResources(_loopEnv_.[[DisposeCapability]], _bodyResult_)).
+ 1. Assert: If _bodyResult_.[[Type]] is ~normal~, then _bodyResult_.[[Value]] is not ~empty~.
1. Set the running execution context's LexicalEnvironment to _oldEnv_.
1. Return ? _bodyResult_.
@@ -21825,7 +22398,7 @@
1. For each element _bn_ of _perIterationBindings_, do
1. Perform ! _thisIterationEnv_.CreateMutableBinding(_bn_, *false*).
1. Let _lastValue_ be ? _lastIterationEnv_.GetBindingValue(_bn_, *true*).
- 1. Perform ! _thisIterationEnv_.InitializeBinding(_bn_, _lastValue_).
+ 1. Perform ! _thisIterationEnv_.InitializeBinding(_bn_, _lastValue_, ~normal~).
1. Set the running execution context's LexicalEnvironment to _thisIterationEnv_.
1. Return ~unused~.
@@ -21838,21 +22411,23 @@ Syntax
ForInOfStatement[Yield, Await, Return] :
`for` `(` [lookahead != `let` `[`] LeftHandSideExpression[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
- `for` `(` `var` ForBinding[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
- `for` `(` ForDeclaration[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` ForBinding[?Yield, ?Await, +Pattern] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` ForDeclaration[?Yield, ?Await, ~Using] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
`for` `(` [lookahead ∉ { `let`, `async` `of` }] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
- `for` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
- `for` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` ForBinding[?Yield, ?Await, +Pattern] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` [lookahead != `using` `of`] ForDeclaration[?Yield, ?Await, +Using] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
[+Await] `for` `await` `(` [lookahead != `let`] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
- [+Await] `for` `await` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
- [+Await] `for` `await` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` `var` ForBinding[?Yield, ?Await, +Pattern] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` [lookahead != `using` `of`] ForDeclaration[?Yield, ?Await, +Using] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
- ForDeclaration[Yield, Await] :
- LetOrConst ForBinding[?Yield, ?Await]
+ ForDeclaration[Yield, Await, Using] :
+ LetOrConst ForBinding[?Yield, ?Await, +Pattern]
+ [+Using] `using` [no LineTerminator here] ForBinding[?Yield, ?Await, ~Pattern]
+ [+Using, +Await] `await` [no LineTerminator here] `using` [no LineTerminator here] ForBinding[?Yield, +Await, ~Pattern]
- ForBinding[Yield, Await] :
+ ForBinding[Yield, Await, Pattern] :
BindingIdentifier[?Yield, ?Await]
- BindingPattern[?Yield, ?Await]
+ [+Pattern] BindingPattern[?Yield, ?Await]
This section is extended by Annex .
@@ -21994,6 +22569,15 @@
1. Perform ! _environment_.CreateMutableBinding(_name_, *false*).
1. Return ~unused~.
+
+ ForDeclaration :
+ `using` ForBinding
+ `await` `using` ForBinding
+
+
+ 1. For each element _name_ of the BoundNames of |ForBinding|, do
+ 1. Perform ! _environment_.CreateImmutableBinding(_name_, *true*).
+
@@ -22114,6 +22698,12 @@
1. If _iteratorKind_ is not present, set _iteratorKind_ to ~sync~.
1. Let _oldEnv_ be the running execution context's LexicalEnvironment.
1. Let _V_ be *undefined*.
+ 1. If IsAwaitUsingDeclaration of _lhs_ is *true*, then
+ 1. Let _hint_ be ~async-dispose~.
+ 1. Else if IsUsingDeclaration of _lhs_ is *true*, then
+ 1. Let _hint_ be ~sync-dispose~.
+ 1. Else,
+ 1. Let _hint_ be ~normal~.
1. Let _destructuring_ be IsDestructuring of _lhs_.
1. If _destructuring_ is *true* and _lhsKind_ is ~assignment~, then
1. Assert: _lhs_ is a |LeftHandSideExpression|.
@@ -22139,6 +22729,7 @@
1. Let _status_ be _lhsRef_.
1. Else,
1. Let _status_ be Completion(PutValue(_lhsRef_.[[Value]], _nextValue_)).
+ 1. Let _iterationEnv_ be *undefined*.
1. Else,
1. Assert: _lhsKind_ is ~lexical-binding~.
1. Assert: _lhs_ is a |ForDeclaration|.
@@ -22151,8 +22742,11 @@
1. Assert: _lhs_ binds a single name.
1. Let _lhsName_ be the sole element of the BoundNames of _lhs_.
1. Let _lhsRef_ be ! ResolveBinding(_lhsName_).
- 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_)).
+ 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, _hint_)).
1. If _status_ is an abrupt completion, then
+ 1. If _iterationEnv_ is not *undefined*, then
+ 1. Set _status_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], _status_)).
+ 1. Assert: _status_ is an abrupt completion.
1. Set the running execution context's LexicalEnvironment to _oldEnv_.
1. If _iteratorKind_ is ~async~, return ? AsyncIteratorClose(_iteratorRecord_, _status_).
1. If _iterationKind_ is ~enumerate~, then
@@ -22161,6 +22755,8 @@
1. Assert: _iterationKind_ is ~iterate~.
1. Return ? IteratorClose(_iteratorRecord_, _status_).
1. Let _result_ be Completion(Evaluation of _stmt_).
+ 1. If _iterationEnv_ is not *undefined*, then
+ 1. Set _result_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], _result_)).
1. Set the running execution context's LexicalEnvironment to _oldEnv_.
1. If LoopContinues(_result_, _labelSet_) is *false*, then
1. If _iterationKind_ is ~enumerate~, then
@@ -22651,6 +23247,8 @@ Runtime Semantics: Evaluation
1. Perform BlockDeclarationInstantiation(|CaseBlock|, _blockEnv_).
1. Set the running execution context's LexicalEnvironment to _blockEnv_.
1. Let _R_ be Completion(CaseBlockEvaluation of |CaseBlock| with argument _switchValue_).
+ 1. Set _R_ to Completion(DisposeResources(_blockEnv_.[[DisposeCapability]], _R_)).
+ 1. Assert: If _R_.[[Type]] is ~normal~, then _R_.[[Value]] is not ~empty~.
1. Set the running execution context's LexicalEnvironment to _oldEnv_.
1. Return _R_.
@@ -23409,7 +24007,7 @@
1. Let _closure_ be OrdinaryFunctionCreate(%Function.prototype%, _sourceText_, |FormalParameters|, |FunctionBody|, ~non-lexical-this~, _funcEnv_, _privateEnv_).
1. Perform SetFunctionName(_closure_, _name_).
1. Perform MakeConstructor(_closure_).
- 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_).
+ 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_, ~normal~).
1. Return _closure_.
@@ -23443,6 +24041,13 @@ Runtime Semantics: Evaluation
1. Return *undefined*.
+ FunctionStatementList : StatementList
+
+ 1. Let _result_ be Completion(Evaluation of |StatementList|).
+ 1. Let _env_ be the running execution context's LexicalEnvironment.
+ 1. Assert: _env_ is a Declarative Environment Record.
+ 1. Return ? DisposeResources(_env_.[[DisposeCapability]], _result_).
+
@@ -23957,7 +24562,7 @@
1. Perform SetFunctionName(_closure_, _name_).
1. Let _prototype_ be OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
1. Perform ! DefinePropertyOrThrow(_closure_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }).
- 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_).
+ 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_, ~normal~).
1. Return _closure_.
@@ -24192,7 +24797,7 @@
1. Perform SetFunctionName(_closure_, _name_).
1. Let _prototype_ be OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
1. Perform ! DefinePropertyOrThrow(_closure_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }).
- 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_).
+ 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_, ~normal~).
1. Return _closure_.
@@ -24731,7 +25336,9 @@
1. Assert: _functionObject_ is a synthetic function created by ClassStaticBlockDefinitionEvaluation step .
1. Perform ! FunctionDeclarationInstantiation(_functionObject_, « »).
- 1. Return ? Evaluation of |ClassStaticBlockStatementList|.
+ 1. Let _result_ be Completion(Evaluation of |ClassStaticBlockStatementList|).
+ 1. Let _env_ be the running execution context's LexicalEnvironment.
+ 1. Return ? DisposeResources(_env_.[[DisposeCapability]], _result_).
@@ -24887,7 +25494,7 @@
1. Append _element_ to _staticElements_.
1. Set the running execution context's LexicalEnvironment to _env_.
1. If _classBinding_ is not *undefined*, then
- 1. Perform ! _classEnv_.InitializeBinding(_classBinding_, _F_).
+ 1. Perform ! _classEnv_.InitializeBinding(_classBinding_, _F_, ~normal~).
1. Set _F_.[[PrivateMethods]] to _instancePrivateMethods_.
1. Set _F_.[[Fields]] to _instanceFields_.
1. For each PrivateElement _method_ of _staticPrivateMethods_, do
@@ -25103,7 +25710,7 @@
1. Let _sourceText_ be the source text matched by |AsyncFunctionExpression|.
1. Let _closure_ be OrdinaryFunctionCreate(%AsyncFunction.prototype%, _sourceText_, |FormalParameters|, |AsyncFunctionBody|, ~non-lexical-this~, _funcEnv_, _privateEnv_).
1. Perform SetFunctionName(_closure_, _name_).
- 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_).
+ 1. Perform ! _funcEnv_.InitializeBinding(_name_, _closure_, ~normal~).
1. Return _closure_.
@@ -25143,6 +25750,13 @@ Runtime Semantics: Evaluation
1. Return InstantiateAsyncFunctionExpression of |AsyncFunctionExpression|.
+
+ UnaryExpression : CoverAwaitExpressionAndAwaitUsingDeclarationHead
+
+
+ 1. Let _expr_ be the |AwaitExpression| that is covered by CoverAwaitExpressionAndAwaitUsingDeclarationHead.
+ 1. Return ? Evaluation of _expr_.
+
AwaitExpression : `await` UnaryExpression
@@ -25331,11 +25945,15 @@
A potential tail position call that is immediately followed by return GetValue of the call result is also a possible tail position call. A function call cannot return a Reference Record, so such a GetValue operation will always return the same value as the actual function call result.
+
+ A `using` declaration or `await using` declaration that precedes a call in the same |Block|, |CaseBlock|, |ForStatement|, |ForInOfStatement|, |FunctionBody|, |GeneratorBody|, |AsyncGeneratorBody|, |AsyncFunctionBody|, or |ClassStaticBlockBody| prevents that call from being a possible tail position call.
+
StatementList : StatementList StatementListItem
1. Let _has_ be HasCallInTailPosition of |StatementList| with argument _call_.
1. If _has_ is *true*, return *true*.
+ 1. If HasUnterminatedUsingDeclaration of |StatementList| is *true*, return *false*.
1. Return HasCallInTailPosition of |StatementListItem| with argument _call_.
@@ -25424,10 +26042,13 @@
CaseBlock : `{` CaseClauses? DefaultClause CaseClauses? `}`
1. Let _has_ be *false*.
- 1. If the first |CaseClauses| is present, set _has_ to HasCallInTailPosition of the first |CaseClauses| with argument _call_.
- 1. If _has_ is *true*, return *true*.
+ 1. If the first |CaseClauses| is present, then
+ 1. Set _has_ to HasCallInTailPosition of the first |CaseClauses| with argument _call_.
+ 1. If _has_ is *true*, return *true*.
+ 1. If HasUnterminatedUsingDeclaration of the first |CaseClauses| is *true*, return *false*.
1. Set _has_ to HasCallInTailPosition of |DefaultClause| with argument _call_.
1. If _has_ is *true*, return *true*.
+ 1. If HasUnterminatedUsingDeclaration of |DefaultClause| is *true*, return *false*.
1. If the second |CaseClauses| is present, set _has_ to HasCallInTailPosition of the second |CaseClauses| with argument _call_.
1. Return _has_.
@@ -25435,6 +26056,7 @@
1. Let _has_ be HasCallInTailPosition of |CaseClauses| with argument _call_.
1. If _has_ is *true*, return *true*.
+ 1. If HasUnterminatedUsingDeclaration of |CaseClauses| is *true*, return *false*.
1. Return HasCallInTailPosition of |CaseClause| with argument _call_.
@@ -25527,7 +26149,10 @@
`-` UnaryExpression
`~` UnaryExpression
`!` UnaryExpression
- AwaitExpression
+ CoverAwaitExpressionAndAwaitUsingDeclarationHead
+
+ AwaitExpression :
+ `await` UnaryExpression
CallExpression :
SuperCall
@@ -25652,6 +26277,65 @@
+
+ Static Semantics: HasUnterminatedUsingDeclaration ( ): a Boolean
+
+ StatementList : StatementList StatementListItem
+
+ 1. Let _has_ be HasUnterminatedUsingDeclaration of |StatementList|.
+ 1. If _has_ is *true*, return *true*.
+ 1. Return HasUnterminatedUsingDeclaration of |StatementListItem|.
+
+
+
+ StatementListItem :
+ Statement
+
+ CaseBlock :
+ `{` `}`
+
+ Declaration :
+ HoistableDeclaration
+ ClassDeclaration
+
+ LexicalDeclaration :
+ LetOrConst BindingList `;`
+
+
+ 1. Return *false*.
+
+
+
+ UsingDeclaration :
+ `using` BindingList `;`
+
+ AwaitUsingDeclaration :
+ CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;`
+
+
+ 1. Return *true*.
+
+
+ CaseClauses : CaseClauses CaseClause
+
+ 1. Let _has_ be HasUnterminatedUsingDeclaration of |CaseClauses|.
+ 1. If _has_ is *true*, return *true*.
+ 1. Return HasUnterminatedUsingDeclaration of |CaseClause|.
+
+
+
+ CaseClause :
+ `case` Expression `:` StatementList?
+
+ DefaultClause :
+ `default` `:` StatementList?
+
+
+ 1. If |StatementList| is present, return HasUnterminatedUsingDeclaration of |StatementList|.
+
+
+
PrepareForTailCall ( ): ~unused~
+
+ %AsyncIteratorPrototype% [ @@asyncDispose ] ( )
+ The following steps are taken:
+
+ 1. Let _O_ be the *this* value.
+ 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
+ 1. Let _return_ be Completion(GetMethod(_O_, `"return"`)).
+ 1. IfAbruptRejectPromise(_return_, _promiseCapability_).
+ 1. If _return_ is *undefined*, then
+ 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « *undefined* »).
+ 1. Else,
+ 1. Let _result_ be Completion(Call(_return_, _O_, « *undefined* »)).
+ 1. IfAbruptRejectPromise(_result_, _promiseCapability_).
+ 1. Let _resultWrapper_ be Completion(PromiseResolve(%Promise%, _result_)).
+ 1. IfAbruptRejectPromise(_resultWrapper_, _promiseCapability_).
+ 1. Let _unwrap_ be a new Abstract Closure that performs the following steps when called:
+ 1. Return *undefined*.
+ 1. Let _onFulfilled_ be CreateBuiltinFunction(_unwrap_, 1, *""*, « »).
+ 1. Perform PerformPromiseThen(_resultWrapper_, _onFulfilled_, *undefined*, _promiseCapability_).
+ 1. Return _promiseCapability_.[[Promise]].
+
+ The value of the *"name"* property of this function is *"[Symbol.asyncDispose]"*.
+
+
%AsyncIteratorPrototype% [ @@asyncIterator ] ( )
This function performs the following steps when called:
@@ -46078,6 +46877,474 @@
+
+ Resource Management
+
+
+ Common Resource Management Interfaces
+
+
+ The Disposable Interface
+ The Disposable interface includes the property described in :
+
+
+
+
+ Property
+ |
+
+ Value
+ |
+
+ Requirements
+ |
+
+
+
+ `@@dispose`
+ |
+
+ a function object
+ |
+
+ Invoking this method notifies the Disposable object that the caller does not intend to continue to use this object. This method should perform any necessary logic to perform explicit clean-up of the resource including, but not limited to, file system handles, streams, host objects, etc. When an exception is thrown from this method, it typically means that the resource could not be explicitly freed.
+ If called more than once on the same object, the function should not throw an exception. However, this requirement is not enforced.
+ When using a Disposable object, it is good practice to create the instance with a `using` declaration, as the resource will be automatically disposed when the |Block| or |Module| immediately containing the declaration has been evaluated.
+ |
+
+
+
+
+
+
+ The AsyncDisposable Interface
+ The AsyncDisposable interface includes the property described in :
+
+
+
+
+ Property
+ |
+
+ Value
+ |
+
+ Requirements
+ |
+
+
+
+ `@@asyncDispose`
+ |
+
+ A function that returns a promise.
+ |
+
+ Invoking this method notifies the AsyncDisposable object that the caller does not intend to continue to use this object. This method should perform any necessary logic to perform explicit clean-up of the resource including, but not limited to, file system handles, streams, host objects, etc. When an exception is thrown from this method, it typically means that the resource could not be explicitly freed. An AsyncDisposable object is not considered "disposed" until the resulting Promise has been fulfilled.
+ If called more than once on the same object, the function should not throw an exception. However, this requirement is not enforced.
+ When using an AsyncDisposable object, it is good practice to create the instance with a `await using` declaration, as the resource will be automatically disposed when the |Block| or |Module| immediately containing the declaration has been evaluated.
+ |
+
+
+
+
+
+
+
+
+ DisposableStack Objects
+ A DisposableStack is an object that can be used to contain one or more resources that should be disposed together.
+ Any DisposableStack object is in one of two mutually exclusive states: disposed or pending:
+
+ - A disposable stack `d` is pending if `d[Symbol.dispose]()` has yet to be invoked for `d`.
+ - A disposable stack `d` is disposed if `d[Symbol.dispose]()` has already been invoked once for `d`.
+
+
+
+ The DisposableStack Constructor
+ The DisposableStack constructor:
+
+ - is %DisposableStack%.
+ - is the initial value of the *"DisposableStack"* property of the global object.
+ - creates and initializes a new DisposableStack when called as a constructor.
+ - is not intended to be called as a function and will throw an exception when called in that manner.
+ - may be used as the value in an `extends` clause of a class definition. Subclass constructors that intend to inherit the specified DisposableStack behaviour must include a `super` call to the DisposableStack constructor to create and initialize the subclass instance with the internal state necessary to support the `DisposableStack` and `DisposableStack.prototype` built-in methods.
+
+
+
+ DisposableStack ( )
+ This function performs the following steps when called:
+
+ 1. If NewTarget is *undefined*, throw a *TypeError* exception.
+ 1. Let _disposableStack_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposeCapability]] »).
+ 1. Set _disposableStack_.[[DisposableState]] to ~pending~.
+ 1. Set _disposableStack_.[[DisposeCapability]] to NewDisposeCapability().
+ 1. Return _disposableStack_.
+
+
+
+
+
+ Properties of the DisposableStack Constructor
+ The DisposableStack constructor:
+
+ - has a [[Prototype]] internal slot whose value is %Function.prototype%.
+ - has the following properties:
+
+
+
+ DisposableStack.prototype
+ The initial value of `DisposableStack.prototype` is the DisposableStack prototype object.
+ This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.
+
+
+
+
+ Properties of the DisposableStack Prototype Object
+ The DisposableStack prototype object:
+
+ - is %DisposableStack.prototype%.
+ - has a [[Prototype]] internal slot whose value is %Object.prototype%.
+ - is an ordinary object.
+ - does not have a [[DisposableState]] internal slot or any of the other internal slots of DisposableStack instances.
+
+
+
+ DisposableStack.prototype.adopt ( _value_, _onDispose_ )
+ This method performs the following steps when called:
+
+ 1. Let _disposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]).
+ 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. If IsCallable(_onDispose_) is *false*, throw a *TypeError* exception.
+ 1. Let _closure_ be a new Abstract Closure with no parameters that captures _value_ and _onDispose_ and performs the following steps when called:
+ 1. Return ? Call(_onDispose_, *undefined*, « _value_ »).
+ 1. Let _F_ be CreateBuiltinFunction(_closure_, 0, *""*, « »).
+ 1. Perform ? AddDisposableResource(_disposableStack_.[[DisposeCapability]], *undefined*, ~sync-dispose~, _F_).
+ 1. Return _value_.
+
+
+
+
+ DisposableStack.prototype.defer ( _onDispose_ )
+ This method performs the following steps when called:
+
+ 1. Let _disposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]).
+ 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. If IsCallable(_onDispose_) is *false*, throw a *TypeError* exception.
+ 1. Perform ? AddDisposableResource(_disposableStack_.[[DisposeCapability]], *undefined*, ~sync-dispose~, _onDispose_).
+ 1. Return *undefined*.
+
+
+
+
+ DisposableStack.prototype.dispose ( )
+ This method performs the following steps when called:
+
+ 1. Let _disposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]).
+ 1. If _disposableStack_.[[DisposableState]] is ~disposed~, return *undefined*.
+ 1. Set _disposableStack_.[[DisposableState]] to ~disposed~.
+ 1. Return ? DisposeResources(_disposableStack_.[[DisposeCapability]], NormalCompletion(*undefined*)).
+
+
+
+
+ get DisposableStack.prototype.disposed
+ `DisposableStack.prototype.disposed` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps when called:
+
+ 1. Let _disposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]).
+ 1. If _disposableStack_.[[DisposableState]] is ~disposed~, return *true*.
+ 1. Otherwise, return *false*.
+
+
+
+
+ DisposableStack.prototype.move ( )
+ This method performs the following steps when called:
+
+ 1. Let _disposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]).
+ 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. Let _newDisposableStack_ be ? OrdinaryCreateFromConstructor(%DisposableStack%, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposeCapability]] »).
+ 1. Set _newDisposableStack_.[[DisposableState]] to ~pending~.
+ 1. Set _newDisposableStack_.[[DisposeCapability]] to _disposableStack_.[[DisposeCapability]].
+ 1. Set _disposableStack_.[[DisposeCapability]] to NewDisposeCapability().
+ 1. Set _disposableStack_.[[DisposableState]] to ~disposed~.
+ 1. Return _newDisposableStack_.
+
+
+
+
+ DisposableStack.prototype.use ( _value_ )
+ This method performs the following steps when called:
+
+ 1. Let _disposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]).
+ 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. Perform ? AddDisposableResource(_disposableStack_.[[DisposeCapability]], _value_, ~sync-dispose~).
+ 1. Return _value_.
+
+
+
+
+ DisposableStack.prototype [ @@dispose ] ( )
+ The initial value of the `@@dispose` property is %DisposableStack.prototype.dispose%, defined in .
+
+
+
+ DisposableStack.prototype [ @@toStringTag ]
+ The initial value of the `@@toStringTag` property is the String value *"DisposableStack"*.
+ This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
+
+
+
+
+ Properties of DisposableStack Instances
+ DisposableStack instances are ordinary objects that inherit properties from the DisposableStack prototype object (the intrinsic %DisposableStack.prototype%). DisposableStack instances are initially created with internal slots described in .
+
+
+
+
+ Internal Slot
+ |
+
+ Type
+ |
+
+ Description
+ |
+
+
+
+ [[DisposableState]]
+ |
+
+ ~pending~ or ~disposed~
+ |
+
+ Governs how a disposable stack will react to incoming calls to its `@@dispose` method.
+ |
+
+
+
+ [[DisposeCapability]]
+ |
+
+ a DisposeCapability Record
+ |
+
+ Resources to be disposed when the disposable stack is disposed.
+ |
+
+
+
+
+
+
+
+ AsyncDisposableStack Objects
+ An AsyncDisposableStack is an object that can be used to contain one or more resources that should be asynchronously disposed together.
+ Any AsyncDisposableStack object is in one of two mutually exclusive states: disposed or pending:
+
+ - An async-disposable stack `d` is pending if `d[Symbol.asyncDispose]()` has yet to be invoked for `d`.
+ - An async-disposable stack `d` is disposed if `d[Symbol.asyncDispose]()` has already been invoked once for `d`.
+
+
+
+ The AsyncDisposableStack Constructor
+ The AsyncDisposableStack constructor:
+
+ - is %AsyncDisposableStack%.
+ - is the initial value of the *"AsyncDisposableStack"* property of the global object.
+ - creates and initializes a new AsyncDisposableStack when called as a constructor.
+ - is not intended to be called as a function and will throw an exception when called in that manner.
+ - may be used as the value in an `extends` clause of a class definition. Subclass constructors that intend to inherit the specified AsyncDisposableStack behaviour must include a `super` call to the AsyncDisposableStack constructor to create and initialize the subclass instance with the internal state necessary to support the `AsyncDisposableStack` and `AsyncDisposableStack.prototype` built-in methods.
+
+
+
+ AsyncDisposableStack ( )
+ When the `AsyncDisposableStack` function is called, the following steps are taken:
+
+ 1. If NewTarget is *undefined*, throw a *TypeError* exception.
+ 1. Let _asyncDisposableStack_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%AsyncDisposableStack.prototype%"*, « [[AsyncDisposableState]], [[DisposeCapability]] »).
+ 1. Set _asyncDisposableStack_.[[AsyncDisposableState]] to ~pending~.
+ 1. Set _asyncDisposableStack_.[[DisposeCapability]] to NewDisposeCapability().
+ 1. Return _asyncDisposableStack_.
+
+
+
+
+
+ Properties of the AsyncDisposableStack Constructor
+ The AsyncDisposableStack constructor:
+
+ - Has a [[Prototype]] internal slot whose value is %Function.prototype%.
+ - has the following properties:
+
+
+
+ AsyncDisposableStack.prototype
+ The initial value of `AsyncDisposableStack.prototype` is the AsyncDisposableStack prototype object.
+ This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.
+
+
+
+
+ Properties of the AsyncDisposableStack Prototype Object
+ The AsyncDisposableStack prototype object:
+
+ - is %AsyncDisposableStack.prototype%.
+ - has a [[Prototype]] internal slot whose value is %Object.prototype%.
+ - is an ordinary object.
+ - does not have an [[AsyncDisposableState]] internal slot or any of the other internal slots of AsyncDisposableStack instances.
+
+
+
+ AsyncDisposableStack.prototype.adopt ( _value_, _onDisposeAsync_ )
+ When the `adopt` function is called with two arguments, the following steps are taken:
+
+ 1. Let _asyncDisposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_asyncDisposableStack_, [[AsyncDisposableState]]).
+ 1. If _asyncDisposableStack_.[[AsyncDisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. If IsCallable(_onDisposeAsync_) is *false*, throw a *TypeError* exception.
+ 1. Let _closure_ be a new Abstract Closure with no parameters that captures _value_ and _onDisposeAsync_ and performs the following steps when called:
+ 1. Return ? Call(_onDisposeAsync_, *undefined*, « _value_ »).
+ 1. Let _F_ be CreateBuiltinFunction(_closure_, 0, *""*, « »).
+ 1. Perform ? AddDisposableResource(_asyncDisposableStack_.[[DisposeCapability]], *undefined*, ~async-dispose~, _F_).
+ 1. Return _value_.
+
+
+
+
+ AsyncDisposableStack.prototype.defer ( _onDisposeAsync_ )
+ When the `defer` function is called with one argument, the following steps are taken:
+
+ 1. Let _asyncDisposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_asyncDisposableStack_, [[AsyncDisposableState]]).
+ 1. If _asyncDisposableStack_.[[AsyncDisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. If IsCallable(_onDisposeAsync_) is *false*, throw a *TypeError* exception.
+ 1. Perform ? AddDisposableResource(_asyncDisposableStack_.[[DisposeCapability]], *undefined*, ~async-dispose~, _onDisposeAsync_).
+ 1. Return *undefined*.
+
+
+
+
+ AsyncDisposableStack.prototype.disposeAsync ( )
+ When the `disposeAsync` method is called, the following steps are taken:
+
+ 1. Let _asyncDisposableStack_ be the *this* value.
+ 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
+ 1. If _asyncDisposableStack_ does not have an [[AsyncDisposableState]] internal slot, then
+ 1. Perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « a newly created *TypeError* object »).
+ 1. Return _promiseCapability_.[[Promise]].
+ 1. If _asyncDisposableStack_.[[AsyncDisposableState]] is ~disposed~, then
+ 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « *undefined* »).
+ 1. Return _promiseCapability_.[[Promise]].
+ 1. Set _asyncDisposableStack_.[[AsyncDisposableState]] to ~disposed~.
+ 1. Let _result_ be Completion(DisposeResources(_asyncDisposableStack_.[[DisposeCapability]], NormalCompletion(*undefined*))).
+ 1. IfAbruptRejectPromise(_result_, _promiseCapability_).
+ 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _result_ »).
+ 1. Return _promiseCapability_.[[Promise]].
+
+
+
+
+ get AsyncDisposableStack.prototype.disposed
+ `AsyncDisposableStack.prototype.disposed` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:
+
+ 1. Let _asyncDisposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_asyncDisposableStack_, [[AsyncDisposableState]]).
+ 1. If _asyncDisposableStack_.[[AsyncDisposableState]] is ~disposed~, return *true*.
+ 1. Otherwise, return *false*.
+
+
+
+
+ AsyncDisposableStack.prototype.move ( )
+ When the `move` function is called, the following steps are taken:
+
+ 1. Let _asyncDisposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_asyncDisposableStack_, [[AsyncDisposableState]]).
+ 1. If _asyncDisposableStack_.[[AsyncDisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. Let _newAsyncDisposableStack_ be ? OrdinaryCreateFromConstructor(%AsyncDisposableStack%, *"%AsyncDisposableStack.prototype%"*, « [[AsyncDisposableState]], [[DisposeCapability]] »).
+ 1. Set _newAsyncDisposableStack_.[[AsyncDisposableState]] to ~pending~.
+ 1. Set _newAsyncDisposableStack_.[[DisposeCapability]] to _asyncDisposableStack_.[[DisposeCapability]].
+ 1. Set _asyncDisposableStack_.[[DisposeCapability]] to NewDisposeCapability().
+ 1. Set _asyncDisposableStack_.[[AsyncDisposableState]] to ~disposed~.
+ 1. Return _newAsyncDisposableStack_.
+
+
+
+
+ AsyncDisposableStack.prototype.use ( _value_ )
+ When the `use` function is called with one argument, the following steps are taken:
+
+ 1. Let _asyncDisposableStack_ be the *this* value.
+ 1. Perform ? RequireInternalSlot(_asyncDisposableStack_, [[AsyncDisposableState]]).
+ 1. If _asyncDisposableStack_.[[AsyncDisposableState]] is ~disposed~, throw a *ReferenceError* exception.
+ 1. Perform ? AddDisposableResource(_asyncDisposableStack_.[[DisposeCapability]], _value_, ~async-dispose~).
+ 1. Return _value_.
+
+
+
+
+ AsyncDisposableStack.prototype [ @@asyncDispose ] ( )
+ The initial value of the `@@asyncDispose` property is %AsyncDisposableStack.prototype.disposeAsync%, defined in .
+
+
+
+ AsyncDisposableStack.prototype [ @@toStringTag ]
+ The initial value of the `@@toStringTag` property is the String value *"AsyncDisposableStack"*.
+ This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
+
+
+
+
+ Properties of AsyncDisposableStack Instances
+ AsyncDisposableStack instances are ordinary objects that inherit properties from the AsyncDisposableStack prototype object (the intrinsic %AsyncDisposableStack.prototype%). AsyncDisposableStack instances are initially created with internal slots described in .
+
+
+
+
+ Internal Slot
+ |
+
+ Type
+ |
+
+ Description
+ |
+
+
+
+ [[AsyncDisposableState]]
+ |
+
+ ~pending~ or ~disposed~
+ |
+
+ Governs how a disposable stack will react to incoming calls to its `@@asyncDispose` method.
+ |
+
+
+
+ [[DisposeCapability]]
+ |
+
+ a DisposeCapability Record
+ |
+
+ Resources to be disposed when the disposable stack is disposed.
+ |
+
+
+
+
+
+
Promise Objects
A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.
@@ -49411,6 +50678,15 @@ Statements
+
+
+
+ In certain circumstances when processing an instance of the production
+
+ the interpretation of |CoverAwaitExpressionAndAwaitUsingDeclarationHead| is refined using the following grammar:
+
+
+
@@ -49504,7 +50780,14 @@ Functions and Classes
+
+
+ When processing an instance of the production
+
+ the interpretation of |CoverAwaitExpressionAndAwaitUsingDeclarationHead| is refined using the following grammar:
+
+
@@ -50439,7 +51722,7 @@ Changes to FunctionDeclarationInstantiation
1. NOTE: A var binding for _F_ is only instantiated here if it is neither a VarDeclaredName, the name of a formal parameter, or another |FunctionDeclaration|.
1. If _instantiatedVarNames_ does not contain _F_ and _F_ is not *"arguments"*, then
1. Perform ! _varEnv_.CreateMutableBinding(_F_, *false*).
- 1. Perform ! _varEnv_.InitializeBinding(_F_, *undefined*).
+ 1. Perform ! _varEnv_.InitializeBinding(_F_, *undefined*, ~normal~).
1. Append _F_ to _instantiatedVarNames_.
1. When the |FunctionDeclaration| _f_ is evaluated, perform the following steps in place of the |FunctionDeclaration| Evaluation algorithm provided in :
1. Let _fenv_ be the running execution context's VariableEnvironment.
@@ -50509,7 +51792,7 @@ Changes to EvalDeclarationInstantiation
1. Let _bindingExists_ be ! _varEnv_.HasBinding(_F_).
1. If _bindingExists_ is *false*, then
1. Perform ! _varEnv_.CreateMutableBinding(_F_, *true*).
- 1. Perform ! _varEnv_.InitializeBinding(_F_, *undefined*).
+ 1. Perform ! _varEnv_.InitializeBinding(_F_, *undefined*, ~normal~).
1. Append _F_ to _declaredFunctionOrVarNames_.
1. When the |FunctionDeclaration| _f_ is evaluated, perform the following steps in place of the |FunctionDeclaration| Evaluation algorithm provided in :
1. Let _genv_ be the running execution context's VariableEnvironment.
@@ -50559,7 +51842,7 @@ Changes to BlockDeclarationInstantiation
1. Perform the following steps:
1. If the binding for _fn_ in _env_ is an uninitialized binding, then
- 1. Perform ! _env_.InitializeBinding(_fn_, _fo_).
+ 1. Perform ! _env_.InitializeBinding(_fn_, _fo_, ~normal~).
1. Else,
1. Assert: _d_ is a |FunctionDeclaration|.
1. Perform ! _env_.SetMutableBinding(_fn_, _fo_, *false*).