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

@@ -4336,7 +4392,7 @@

1. Assert: IsUnresolvableReference(_V_) is *false*. 1. Let _base_ be _V_.[[Base]]. 1. Assert: _base_ is an Environment Record. - 1. Return ? _base_.InitializeBinding(_V_.[[ReferencedName]], _W_). + 1. Return ? _base_.InitializeBinding(_V_.[[ReferencedName]], _W_, _hint_). @@ -7137,6 +7193,251 @@

+ + +

Operations on Disposable Objects

+

See Common Resource Management Interfaces ().

+ + +

DisposeCapability Records

+

A DisposeCapability Record is a Record value used to contain a List of DisposableResource Records that are disposed together. DisposeCapability Records are produced by the NewDisposeCapability abstract operation.

+

DisposeCapability Records have the fields listed in :

+ + + + + + + + + + + + +
+ Field Name + + Value + + Meaning +
+ [[DisposableResourceStack]] + + a List of DisposableResource Records + + The resources to be disposed. Resources are added in the order they are initialized, and are disposed in reverse order. +
+
+
+ + +

DisposableResource Records

+

A DisposableResource Record is a Record value used to encapsulate a disposable object along with the method used to dispose the object. DisposableResource Records are produced by the CreateDisposableResource abstract operation.

+

DisposableResource Records have the fields listed in :

+ + + + + + + + + + + + + + + + + + + + + + +
+ Field Name + + Value + + Meaning +
+ [[ResourceValue]] + + an Object or *undefined*. + + The value to be disposed. +
+ [[Hint]] + + ~sync-dispose~ or ~async-dispose~ + + Indicates whether the resource was added by a `using` declaration or DisposableStack object (~sync-dispose~) or by an `await using` declaration or AsyncDisposableStack object (~async-dispose~). +
+ [[DisposeMethod]] + + a function object or *undefined* + + A function object that will be called with [[ResourceValue]] as its *this* value when the resource disposed. +
+
+
+ + +

NewDisposeCapability ( ): a DisposeCapability Record

+
+
+ + 1. Let _stack_ be a new empty List. + 1. Return the DisposeCapability Record { [[DisposableResourceStack]]: _stack_ }. + +
+ + +

+ AddDisposableResource ( + _disposeCapability_: a DisposeCapability Record, + _V_: an ECMAScript language value, + _hint_: either ~sync-dispose~ or ~async-dispose~, + optional _method_: a function object, + ): either a normal completion containing ~unused~ or a throw completion +

+
+
+ + 1. If _method_ is not present, then + 1. If _V_ is either *null* or *undefined* and _hint_ is ~sync-dispose~, return ~unused~. + 1. NOTE: When _V_ is either *null* or *undefined* and _hint_ is ~async-dispose~, we record that the resource was evaluated to ensure we will still perform an Await when resources are later disposed. + 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_). + 1. Else, + 1. Assert: V is *undefined*. + 1. Let _resource_ be ? CreateDisposableResource(*undefined*, _hint_, _method_). + 1. Append _resource_ to _disposeCapability_.[[DisposableResourceStack]]. + 1. Return ~unused~. + +
+ + +

+ CreateDisposableResource ( + _V_: an ECMAScript language value, + _hint_: either ~sync-dispose~ or ~async-dispose~, + optional _method_: a function object, + ): either a normal completion containing a DisposableResource Record or a throw completion +

+
+
+ + 1. If _method_ is not present, then + 1. If _V_ is either *null* or *undefined*, then + 1. Set _V_ to *undefined*. + 1. Set _method_ to *undefined*. + 1. Else, + 1. If _V_ is not an Object, throw a *TypeError* exception. + 1. Set _method_ to ? GetDisposeMethod(_V_, _hint_). + 1. If _method_ is *undefined*, throw a *TypeError* exception. + 1. Else, + 1. If IsCallable(_method_) is *false*, throw a *TypeError* exception. + 1. Return the DisposableResource Record { [[ResourceValue]]: _V_, [[Hint]]: _hint_, [[DisposeMethod]]: _method_ }. + +
+ + +

+ GetDisposeMethod ( + _V_: an Object, + _hint_: either ~sync-dispose~ or ~async-dispose~, + ): either a normal completion containing either a function object or *undefined*, or a throw completion +

+
+
+ + 1. If _hint_ is ~async-dispose~, then + 1. Let _method_ be ? GetMethod(_V_, @@asyncDispose). + 1. If _method_ is *undefined*, then + 1. Set _method_ to ? GetMethod(_V_, @@dispose). + 1. If _method_ is not *undefined*, then + 1. Let _closure_ be a new Abstract Closure with no parameters that captures _method_ and performs the following steps when called: + 1. Let _O_ be the *this* value. + 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%). + 1. Let _result_ be Completion(Call(_method_, _O_)). + 1. IfAbruptRejectPromise(_result_, _promiseCapability_). + 1. Perform ? Call(_promiseCapability_.[[Resolve]], *undefined*, « *undefined* »). + 1. Return _promiseCapability_.[[Promise]]. + 1. NOTE: This function is not observable to user code. It is used to ensure that a Promise returned from a synchronous `@@dispose` method will not be awaited and that any exception thrown will not be thrown synchronously. + 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). + 1. Else, + 1. Let _method_ be ? GetMethod(_V_, @@dispose). + 1. Return _method_. + +
+ + +

+ Dispose ( + _V_: an Object or *undefined*, + _hint_: either ~sync-dispose~ or ~async-dispose~, + _method_: a function object or *undefined*, + ): either a normal completion containing *undefined* or a throw completion +

+
+
+ + 1. If _method_ is *undefined*, let _result_ be *undefined*. + 1. Else, let _result_ be ? Call(_method_, _V_). + 1. If _hint_ is ~async-dispose~, then + 1. Perform ? Await(_result_). + 1. Return *undefined*. + +
+ + +

+ DisposeResources ( + _disposeCapability_: a DisposeCapability Record, + _completion_: either a normal completion containing either an ECMAScript language value or ~empty~, or an abrupt completion, + ): either a normal completion containing either an ECMAScript language value or ~empty~, or an abrupt completion +

+
+
+ + 1. Let _needsAwait_ be *false*. + 1. Let _hasAwaited_ be *false*. + 1. For each element _resource_ of _disposeCapability_.[[DisposableResourceStack]], in reverse list order, do + 1. Let _value_ be _resource_.[[ResourceValue]]. + 1. Let _hint_ be _resource_.[[Hint]]. + 1. Let _method_ be _resource_.[[DisposeMethod]]. + 1. If _hint_ is ~sync-dispose~ and _needsAwait_ is *true* and _hasAwaited_ is *false*, then + 1. Perform ! Await(*undefined*). + 1. Set _needsAwait_ to *false*. + 1. If _method_ is not *undefined*, then + 1. Let _result_ be Completion(Call(_method_, _value_)). + 1. If _result_ is a normal completion and _hint_ is ~async-dispose~, then + 1. Set _result_ to Completion(Await(_result_.[[Value]])). + 1. Set _hasAwaited_ to *true*. + 1. If _result_ is a throw completion, then + 1. If _completion_ is a throw completion, then + 1. Set _result_ to _result_.[[Value]]. + 1. Let _suppressed_ be _completion_.[[Value]]. + 1. Let _error_ be a newly created *SuppressedError* object. + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_error_, *"error"*, _result_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_error_, *"suppressed"*, _suppressed_). + 1. Set _completion_ to ThrowCompletion(_error_). + 1. Else, + 1. Set _completion_ to _result_. + 1. Else, + 1. Assert: _hint_ is ~async-dispose~. + 1. Set _needsAwait_ to *true*. + 1. NOTE: This can only indicate a case where either *null* or *undefined* was the initialized value of an `await using` declaration. + 1. If _needsAwait_ is *true* and _hasAwaited_ is *false*, then + 1. Perform ! Await(*undefined*). + 1. NOTE: After _disposeCapability_ has been disposed, it will never be used again. The contents of _disposeCapability_.[[DisposableResourceStack]] can be discarded in implementations, such as by garbage collection, at this point. + 1. Set _disposeCapability_.[[DisposableResourceStack]] to a new empty List. + 1. Return ? _completion_. + +
+
@@ -7180,6 +7481,16 @@

Static Semantics: BoundNames ( ): a List of Strings

1. Return the BoundNames of |BindingList|. + + UsingDeclaration : + `using` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` + + + 1. Return the BoundNames of |BindingList|. + BindingList : BindingList `,` LexicalBinding 1. Let _names1_ be the BoundNames of |BindingList|. @@ -7454,6 +7765,16 @@

Static Semantics: IsConstantDeclaration ( ): a Boolean

1. Return *true*. + + UsingDeclaration : + `using` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` + + + 1. Return *true*. + FunctionDeclaration : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}` @@ -7496,6 +7817,142 @@

Static Semantics: IsConstantDeclaration ( ): a Boolean

+ +

Static Semantics: IsUsingDeclaration ( ): a Boolean

+
+
+ LexicalDeclaration : LetOrConst BindingList `;` + + 1. Return *false*. + + + UsingDeclaration : + `using` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` + + + 1. Return *true*. + + ForDeclaration : LetOrConst ForBinding + + 1. Return *false*. + + + ForDeclaration : + `using` ForBinding + `await` `using` ForBinding + + + 1. Return *true*. + + + FunctionDeclaration : + `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}` + `function` `(` FormalParameters `)` `{` FunctionBody `}` + + GeneratorDeclaration : + `function` `*` BindingIdentifier `(` FormalParameters `)` `{` GeneratorBody `}` + `function` `*` `(` FormalParameters `)` `{` GeneratorBody `}` + + AsyncGeneratorDeclaration : + `async` `function` `*` BindingIdentifier `(` FormalParameters `)` `{` AsyncGeneratorBody `}` + `async` `function` `*` `(` FormalParameters `)` `{` AsyncGeneratorBody `}` + + AsyncFunctionDeclaration : + `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}` + `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}` + + + 1. Return *false*. + + + ClassDeclaration : + `class` BindingIdentifier ClassTail + `class` ClassTail + + + 1. Return *false*. + + + ExportDeclaration : + `export` ExportFromClause FromClause `;` + `export` NamedExports `;` + `export` `default` AssignmentExpression `;` + + + 1. Return *false*. + +
+ + +

Static Semantics: IsAwaitUsingDeclaration ( ): a Boolean

+
+
+ LexicalDeclaration : LetOrConst BindingList `;` + + 1. Return *false*. + + UsingDeclaration : `using` BindingList `;` + + 1. Return *false*. + + AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` + + 1. Return *true*. + + ForDeclaration : LetOrConst ForBinding + + 1. Return *false*. + + ForDeclaration : `using` ForBinding + + 1. Return *false*. + + ForDeclaration : `await` `using` ForBinding + + 1. Return *true*. + + + FunctionDeclaration : + `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}` + `function` `(` FormalParameters `)` `{` FunctionBody `}` + + GeneratorDeclaration : + `function` `*` BindingIdentifier `(` FormalParameters `)` `{` GeneratorBody `}` + `function` `*` `(` FormalParameters `)` `{` GeneratorBody `}` + + AsyncGeneratorDeclaration : + `async` `function` `*` BindingIdentifier `(` FormalParameters `)` `{` AsyncGeneratorBody `}` + `async` `function` `*` `(` FormalParameters `)` `{` AsyncGeneratorBody `}` + + AsyncFunctionDeclaration : + `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}` + `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}` + + + 1. Return *false*. + + + ClassDeclaration : + `class` BindingIdentifier ClassTail + `class` ClassTail + + + 1. Return *false*. + + + ExportDeclaration : + `export` ExportFromClause FromClause `;` + `export` NamedExports `;` + `export` `default` AssignmentExpression `;` + + + 1. Return *false*. + +
+

Static Semantics: LexicallyDeclaredNames ( ): a List of Strings

@@ -8969,7 +9426,10 @@

Static Semantics: IsFunctionDefinition ( ): a Boolean

`-` UnaryExpression `~` UnaryExpression `!` UnaryExpression - AwaitExpression + CoverAwaitExpressionAndAwaitUsingDeclarationHead + + AwaitExpression : + `await` UnaryExpression ExponentiationExpression : UpdateExpression `**` ExponentiationExpression @@ -9507,7 +9967,7 @@

1. If _environment_ is not *undefined*, then - 1. Perform ! _environment_.InitializeBinding(_name_, _value_). + 1. Perform ! _environment_.InitializeBinding(_name_, _value_, ~normal~). 1. Return ~unused~. 1. Else, 1. Let _lhs_ be ? ResolveBinding(_name_). @@ -9580,7 +10040,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~). BindingElement : BindingPattern Initializer? @@ -9605,7 +10065,7 @@

1. Set _next_ to ? IteratorStepValue(_iteratorRecord_). 1. If _next_ is ~done~, then 1. If _environment_ is *undefined*, return ? PutValue(_lhs_, _A_). - 1. Return ? InitializeReferencedBinding(_lhs_, _A_). + 1. Return ? InitializeReferencedBinding(_lhs_, _A_, ~normal~). 1. Perform ! CreateDataPropertyOrThrow(_A_, ! ToString(𝔽(_n_)), _next_). 1. Set _n_ to _n_ + 1. @@ -9750,7 +10210,10 @@

Static Semantics: AssignmentTargetType ( ): ~simple~ or ~invalid~

`-` UnaryExpression `~` UnaryExpression `!` UnaryExpression - AwaitExpression + CoverAwaitExpressionAndAwaitUsingDeclarationHead + + AwaitExpression : + `await` UnaryExpression ExponentiationExpression : UpdateExpression `**` ExponentiationExpression @@ -9975,10 +10438,10 @@

The Environment Record Type Hierarchy

- 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

for
@@ -10114,6 +10579,7 @@

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

@@ -10353,6 +10820,7 @@

It is used to set the bound value of the current binding of the identifier whose name is _N_ to the value _V_.

+ 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

@@ -10863,10 +11332,11 @@

1. Let _DclRec_ be _envRec_.[[DeclarativeRecord]]. 1. If ! _DclRec_.HasBinding(_N_) is *true*, then - 1. Return ! _DclRec_.InitializeBinding(_N_, _V_). + 1. Return ? _DclRec_.InitializeBinding(_N_, _V_, _hint_). + 1. Assert: _hint_ is ~normal~. 1. Assert: If the binding exists, it must be in the Object Environment Record. 1. Let _ObjRec_ be _envRec_.[[ObjectRecord]]. - 1. Return ? _ObjRec_.InitializeBinding(_N_, _V_). + 1. Return ? _ObjRec_.InitializeBinding(_N_, _V_, ~normal~). @@ -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~

    @@ -27926,14 +28610,14 @@

    InitializeEnvironment ( ): either a normal completion containing ~unused~ or 1. If _in_.[[ImportName]] is ~namespace-object~, then 1. Let _namespace_ be GetModuleNamespace(_importedModule_). 1. Perform ! _env_.CreateImmutableBinding(_in_.[[LocalName]], *true*). - 1. Perform ! _env_.InitializeBinding(_in_.[[LocalName]], _namespace_). + 1. Perform ! _env_.InitializeBinding(_in_.[[LocalName]], _namespace_, ~normal~). 1. Else, 1. Let _resolution_ be _importedModule_.ResolveExport(_in_.[[ImportName]]). 1. If _resolution_ is either *null* or ~ambiguous~, throw a *SyntaxError* exception. 1. If _resolution_.[[BindingName]] is ~namespace~, then 1. Let _namespace_ be GetModuleNamespace(_resolution_.[[Module]]). 1. Perform ! _env_.CreateImmutableBinding(_in_.[[LocalName]], *true*). - 1. Perform ! _env_.InitializeBinding(_in_.[[LocalName]], _namespace_). + 1. Perform ! _env_.InitializeBinding(_in_.[[LocalName]], _namespace_, ~normal~). 1. Else, 1. Perform _env_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). 1. Let _moduleContext_ be a new ECMAScript code execution context. @@ -27953,7 +28637,7 @@

    InitializeEnvironment ( ): either a normal completion containing ~unused~ or 1. For each element _dn_ of the BoundNames of _d_, do 1. If _declaredVarNames_ does not contain _dn_, then 1. Perform ! _env_.CreateMutableBinding(_dn_, *false*). - 1. Perform ! _env_.InitializeBinding(_dn_, *undefined*). + 1. Perform ! _env_.InitializeBinding(_dn_, *undefined*, ~normal~). 1. Append _dn_ to _declaredVarNames_. 1. Let _lexDeclarations_ be the LexicallyScopedDeclarations of _code_. 1. Let _privateEnv_ be *null*. @@ -27965,7 +28649,7 @@

    InitializeEnvironment ( ): either a normal completion containing ~unused~ or 1. Perform ! _env_.CreateMutableBinding(_dn_, *false*). 1. If _d_ is either a |FunctionDeclaration|, a |GeneratorDeclaration|, an |AsyncFunctionDeclaration|, or an |AsyncGeneratorDeclaration|, then 1. Let _fo_ be InstantiateFunctionObject of _d_ with arguments _env_ and _privateEnv_. - 1. Perform ! _env_.InitializeBinding(_dn_, _fo_). + 1. Perform ! _env_.InitializeBinding(_dn_, _fo_, ~normal~). 1. Remove _moduleContext_ from the execution context stack. 1. Return ~unused~. @@ -27988,13 +28672,15 @@

    1. Set the Realm of _moduleContext_ to _module_.[[Realm]]. 1. Set the ScriptOrModule of _moduleContext_ to _module_. 1. Assert: _module_ has been linked and declarations in its module environment have been instantiated. - 1. Set the VariableEnvironment of _moduleContext_ to _module_.[[Environment]]. - 1. Set the LexicalEnvironment of _moduleContext_ to _module_.[[Environment]]. + 1. Let _env_ be _module_.[[Environment]]. + 1. Set the VariableEnvironment of _moduleContext_ to _env_. + 1. Set the LexicalEnvironment of _moduleContext_ to _env_. 1. Suspend the running execution context. 1. If _module_.[[HasTLA]] is *false*, then 1. Assert: _capability_ is not present. 1. Push _moduleContext_ onto the execution context stack; _moduleContext_ is now the running execution context. 1. Let _result_ be Completion(Evaluation of _module_.[[ECMAScriptCode]]). + 1. Set _result_ to Completion(DisposeResources(_env_.[[DisposeCapability]], _result_)). 1. Suspend _moduleContext_ and remove it from the execution context stack. 1. Resume the context that is now on the top of the execution context stack as the running execution context. 1. If _result_ is an abrupt completion, then @@ -28301,7 +28987,7 @@

    Syntax

    `export` ExportFromClause FromClause `;` `export` NamedExports `;` `export` VariableStatement[~Yield, +Await] - `export` Declaration[~Yield, +Await] + `export` [lookahead ∉ { `using`, `await` }] Declaration[~Yield, +Await] `export` `default` HoistableDeclaration[~Yield, +Await, +Default] `export` `default` ClassDeclaration[~Yield, +Await, +Default] `export` `default` [lookahead ∉ { `function`, `async` [no LineTerminator here] `function`, `class` }] AssignmentExpression[+In, ~Yield, +Await] `;` @@ -28999,7 +29685,7 @@

    1. If _bindingExists_ is *false*, then 1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step . 1. Perform ! _varEnv_.CreateMutableBinding(_fn_, *true*). - 1. Perform ! _varEnv_.InitializeBinding(_fn_, _fo_). + 1. Perform ! _varEnv_.InitializeBinding(_fn_, _fo_, ~normal~). 1. Else, 1. Perform ! _varEnv_.SetMutableBinding(_fn_, _fo_, *false*). 1. For each String _vn_ of _declaredVarNames_, do @@ -29010,7 +29696,7 @@

    1. If _bindingExists_ is *false*, then 1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step . 1. Perform ! _varEnv_.CreateMutableBinding(_vn_, *true*). - 1. Perform ! _varEnv_.InitializeBinding(_vn_, *undefined*). + 1. Perform ! _varEnv_.InitializeBinding(_vn_, *undefined*, ~normal~). 1. Return ~unused~. @@ -30798,7 +31484,7 @@

    Error Objects

    Instances of Error objects are thrown as exceptions when runtime errors occur. The Error objects may also serve as base objects for user-defined exception classes.

    -

    When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the _NativeError_ objects defined in or a new instance of the AggregateError object defined in .

    +

    When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the _NativeError_ objects defined in or a new instance of either the AggregateError object defined in , or the SuppressedError object defined in . Each of these objects has the structure described below, differing only in the name used as the constructor name instead of _NativeError_, in the *"name"* property of the prototype object, in the implementation-defined *"message"* property of the prototype object, and in the presence of the %AggregateError%-specific *"errors"* property or the %SuppressedError%-specific *"error"* and *"suppressed"* properties.

    The Error Constructor

    @@ -30884,12 +31570,12 @@

    Error.prototype.toString ( )

    Properties of Error Instances

    -

    Error instances are ordinary objects that inherit properties from the Error prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified uses of [[ErrorData]] is to identify Error, AggregateError, and _NativeError_ instances as Error objects within `Object.prototype.toString`.

    +

    Error instances are ordinary objects that inherit properties from the Error prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified uses of [[ErrorData]] is to identify Error, AggregateError, SuppressedError, and _NativeError_ instances as Error objects within `Object.prototype.toString`.

    Native Error Types Used in This Standard

    -

    A new instance of one of the _NativeError_ objects below or of the AggregateError object is thrown when a runtime error is detected. All _NativeError_ objects share the same structure, as described in .

    +

    A new instance of one of the _NativeError_ objects below or of either the AggregateError object or SuppressedError object is thrown when a runtime error is detected. All _NativeError_ objects share the same structure, as described in .

    EvalError

    @@ -31000,7 +31686,7 @@

    _NativeError_.prototype.name

    Properties of _NativeError_ Instances

    -

    _NativeError_ instances are ordinary objects that inherit properties from their _NativeError_ prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified use of [[ErrorData]] is by `Object.prototype.toString` () to identify Error, AggregateError, or _NativeError_ instances.

    +

    _NativeError_ instances are ordinary objects that inherit properties from their _NativeError_ prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified use of [[ErrorData]] is by `Object.prototype.toString` () to identify Error, AggregateError, SuppressedError, or _NativeError_ instances.

    @@ -31077,7 +31763,83 @@

    AggregateError.prototype.name

    Properties of AggregateError Instances

    -

    AggregateError instances are ordinary objects that inherit properties from their AggregateError prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified use of [[ErrorData]] is by `Object.prototype.toString` () to identify Error, AggregateError, or _NativeError_ instances.

    +

    AggregateError instances are ordinary objects that inherit properties from their AggregateError prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified use of [[ErrorData]] is by `Object.prototype.toString` () to identify Error, AggregateError, SuppressedError, or _NativeError_ instances.

    +
    +
    + + +

    SuppressedError Objects

    + + +

    The SuppressedError Constructor

    +

    The SuppressedError constructor:

    +
      +
    • is %SuppressedError%.
    • +
    • is the initial value of the *"SuppressedError"* property of the global object.
    • +
    • creates and initializes a new SuppressedError object when called as a function rather than as a constructor. Thus the function call `SuppressedError(…)` is equivalent to the object creation expression `new SuppressedError(…)` with the same arguments.
    • +
    • may be used as the value of an `extends` clause of a class definition. Subclass constructors that intend to inherit the specified SuppressedError behaviour must include a `super` call to the SuppressedError constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.
    • +
    + + +

    SuppressedError ( _error_, _suppressed_, _message_ )

    +

    This function performs the following steps when called:

    + + 1. If NewTarget is *undefined*, let _newTarget_ be the active function object; else let _newTarget_ be NewTarget. + 1. Let _O_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%SuppressedError.prototype%"*, « [[ErrorData]] »). + 1. If _message_ is not *undefined*, then + 1. Let _messageString_ be ? ToString(_message_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"message"*, _messageString_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"error"*, _error_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"suppressed"*, _suppressed_). + 1. Return _O_. + +
    +
    + + +

    Properties of the SuppressedError Constructor

    +

    The SuppressedError constructor:

    +
      +
    • has a [[Prototype]] internal slot whose value is %Error%.
    • +
    • has the following properties:
    • +
    + + +

    SuppressedError.prototype

    +

    The initial value of `SuppressedError.prototype` is %SuppressedError.prototype%.

    +

    This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.

    +
    +
    + + +

    Properties of the SuppressedError Prototype Object

    +

    The SuppressedError prototype object:

    +
      +
    • is %SuppressedError.prototype%.
    • +
    • is an ordinary object.
    • +
    • is not an Error instance or an SuppressedError instance and does not have an [[ErrorData]] internal slot.
    • +
    • has a [[Prototype]] internal slot whose value is %Error.prototype%.
    • +
    + + +

    SuppressedError.prototype.constructor

    +

    The initial value of `SuppressedError.prototype.constructor` is %SuppressedError%.

    +
    + + +

    SuppressedError.prototype.message

    +

    The initial value of `SuppressedError.prototype.message` is the empty String.

    +
    + + +

    SuppressedError.prototype.name

    +

    The initial value of `SuppressedError.prototype.name` is *"SuppressedError"*.

    +
    +
    + + +

    Properties of SuppressedError Instances

    +

    SuppressedError instances are ordinary objects that inherit properties from their SuppressedError prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified use of [[ErrorData]] is by `Object.prototype.toString` () to identify Error, AggregateError, SuppressedError, or _NativeError_ instances.

    @@ -45882,6 +46644,19 @@

    The %IteratorPrototype% Object

    Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
    + +

    %IteratorPrototype% [ @@dispose ] ( )

    +

    This function performs the following steps when called:

    + + 1. Let _O_ be the *this* value. + 1. Let _return_ be ? GetMethod(_O_, *"return"*). + 1. If _return_ is not *undefined*, then + 1. Perform ? Call(_return_, _O_, « »). + 1. Return NormalCompletion(~empty~). + +

    The value of the *"name"* property of this function is *"[Symbol.dispose]"*.

    +
    +

    %IteratorPrototype% [ @@iterator ] ( )

    This function performs the following steps when called:

    @@ -45903,6 +46678,30 @@

    The %AsyncIteratorPrototype% Object

    All objects defined in this specification that implement the AsyncIterator interface also inherit from %AsyncIteratorPrototype%. ECMAScript code may also define objects that inherit from %AsyncIteratorPrototype%. The %AsyncIteratorPrototype% object provides a place where additional methods that are applicable to all async iterator objects may be added.

    + +

    %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*).