From 9b03205ed3853befe0a88955a152da2fa12f0843 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 17:34:53 -0500 Subject: [PATCH 01/56] Spec text for proposal-explicit-resource-management --- package-lock.json | 1 - spec.html | 867 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 801 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index bd2ac49ed1..deb1067a82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,6 @@ "requires": true, "packages": { "": { - "name": "ecma262", "version": "1.0.0", "license": "SEE LICENSE IN https://tc39.es/ecma262/#sec-copyright-and-software-license", "devDependencies": { diff --git a/spec.html b/spec.html index b53a6a0c3b..1e6ad487a1 100644 --- a/spec.html +++ b/spec.html @@ -1232,6 +1232,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 @@ -3437,6 +3448,17 @@

Well-Known Intrinsic Objects

The `decodeURIComponent` function () + + + %DisposableStack% + + + `DisposableStack` + + + The DisposableStack constructor () + + %encodeURI% @@ -3847,6 +3869,17 @@

Well-Known Intrinsic Objects

The prototype of String iterator objects () + + + %SuppressedError% + + + `SuppressedError` + + + The `SuppressedError` constructor () + + %Symbol% @@ -4328,6 +4361,7 @@

InitializeReferencedBinding ( _V_: a Reference Record, _W_: an ECMAScript language value, + _hint_: either ~normal~ or ~sync-dispose~, ): either a normal completion containing ~unused~ or an abrupt completion

@@ -4336,7 +4370,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 +7171,179 @@

+ + +

Operations on Disposable Objects

+

See Common Resource Management Interfaces ().

+ +

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~. + + Indicates that the resource was added by a `using` declaration or DisposableStack object. +
+ [[DisposeMethod]] + + A function object. + + A function object that will be called with [[ResourceValue]] as its *this* value when the resource disposed. +
+
+ + Currently, the only allowed value for [[Hint]] is ~sync-dispose~. + +
+ + +

+ AddDisposableResource ( + _disposable_ : an object with a [[DisposableResourceStack]] internal slot, + _V_ : an ECMAScript language value, + _hint_ : ~sync-dispose~, + optional _method_ : a function object, + ) +

+
+
+ + 1. If _method_ is not present then, + 1. If _V_ is *null* or *undefined*, return NormalCompletion(~empty~). + 1. If Type(_V_) is not Object, throw a *TypeError* exception. + 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_). + 1. Else, + 1. If _V_ is *null* or *undefined*, then + 1. Let _resource_ be ? CreateDisposableResource(*undefined*, _hint_, _method_). + 1. Else, + 1. If Type(_V_) is not Object, throw a *TypeError* exception. + 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_, _method_). + 1. Append _resource_ to _disposable_.[[DisposableResourceStack]]. + 1. Return NormalCompletion(~empty~). + + + Currently, the only allowed value for _hint_ is ~sync-dispose~. + +
+ + +

+ CreateDisposableResource ( + _V_ : an Object or *undefined*, + _hint_ : ~sync-dispose~, + optional _method_ : a function object, + ) +

+
+ + 1. If _method_ is not present, then + 1. If _V_ is *undefined*, 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_ }. + + + Currently, the only allowed value for _hint_ is ~sync-dispose~. + +
+ + +

+ GetDisposeMethod ( + _V_ : an Object, + _hint_ : ~sync-dispose~, + ) +

+
+ + 1. Assert: _hint_ is ~sync-dispose~. + 1. Let _method_ be ? GetMethod(_V_, @@dispose). + 1. Return _method_. + +
+ + +

+ Dispose ( + _V_ : an Object or *undefined*, + _hint_ : ~sync-dispose~, + _method_ : a function object, + ) +

+
+ + 1. Assert: _hint_ is ~sync-dispose~. + 1. Perform ? Call(_method_, _V_). + 1. Return *undefined*. + +
+ + +

+ DisposeResources ( + _disposable_ : an object with a [[DisposableResourceStack]] internal slot or *undefined*, + _completion_ : a Completion Record, + ): a Completion Record +

+
+ + 1. If _disposable_ is not *undefined*, then + 1. For each _resource_ of _disposable_.[[DisposableResourceStack]], in reverse list order, do + 1. Let _result_ be Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]]). + 1. If _result_.[[Type]] is ~throw~, then + 1. If _completion_.[[Type]] is ~throw~, 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. Return _completion_. + +
+
@@ -7180,6 +7387,10 @@

Static Semantics: BoundNames ( ): a List of Strings

1. Return the BoundNames of |BindingList|. + UsingDeclaration : `using` BindingList `;` + + 1. Return the BoundNames of |BindingList|. + BindingList : BindingList `,` LexicalBinding 1. Let _names1_ be the BoundNames of |BindingList|. @@ -7446,6 +7657,10 @@

Static Semantics: IsConstantDeclaration ( ): a Boolean

1. Return IsConstantDeclaration of |LetOrConst|. + LexicalDeclaration : UsingDeclaration + + 1. Return *true*. + LetOrConst : `let` 1. Return *false*. @@ -7496,6 +7711,65 @@

Static Semantics: IsConstantDeclaration ( ): a Boolean

+ +

Static Semantics: IsUsingDeclaration ( ): a Boolean

+
+
+ LexicalDeclaration : LetOrConst BindingList `;` + + 1. Return *false*. + + LexicalDeclaration : UsingDeclaration + + 1. Return *true*. + + ForDeclaration : LetOrConst ForBinding + + 1. Return *false*. + + ForDeclaration : `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

@@ -9580,7 +9854,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 +9879,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. @@ -9975,10 +10249,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~) or a regular variable declaration (~normal~). @@ -10035,6 +10309,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 [[DisposableResourceStack]] field, which is a List of DisposableResource Records. This list is a stack of resources tracked by the `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,6 +10378,7 @@

InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, + _hint_: either ~normal~ or ~sync-dispose~, ): a normal completion containing ~unused~

@@ -10114,6 +10390,7 @@

1. Assert: _envRec_ must have an uninitialized binding for _N_. + 1. If _hint_ is not ~normal~, perform ? AddDisposableResource(_envRec_, _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~. @@ -10343,6 +10620,7 @@

InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, + _hint_: either ~normal~ or ~sync-dispose~, ): either a normal completion containing ~unused~ or a throw completion

@@ -10353,6 +10631,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 +11130,7 @@

InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, + _hint_: either ~normal~ or ~sync-dispose~, ): either a normal completion containing ~unused~ or a throw completion

@@ -10863,7 +11143,8 @@

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_). @@ -13670,7 +13951,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 +13963,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 +13979,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 +13994,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 +16878,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 `_`;

    @@ -21104,6 +21385,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_, _blockValue_)). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return ? _blockValue_. @@ -21158,7 +21440,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 +21449,34 @@

    Declarations and the Variable Statement

    - -

    Let and Const Declarations

    + +

    Let, Const, and 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`, and `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, ~Using] `;` + UsingDeclaration[?In, ?Yield, ?Await] 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] [lookahead != `await`] BindingList[?In, ?Yield, ?Await, +Using] `;` - LexicalBinding[In, Yield, Await] : + BindingList[In, Yield, Await, Using] : + LexicalBinding[?In, ?Yield, ?Await, ?Using] + BindingList[?In, ?Yield, ?Await, ?Using] `,` LexicalBinding[?In, ?Yield, ?Await, ?Using] + + LexicalBinding[In, Yield, Await, Using] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]? - BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] + [~Using] BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] - +

    Static Semantics: Early Errors

    LexicalDeclaration : LetOrConst BindingList `;`
      @@ -21201,6 +21487,21 @@

      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"* or *"await"*. +
    • +
    • + 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|, |ClassStaticBlockBody|, or |ClassBody|. +
    • +
    LexicalBinding : BindingIdentifier Initializer?
    • @@ -21209,26 +21510,42 @@

      Static Semantics: Early Errors

    - +

    Runtime Semantics: Evaluation

    LexicalDeclaration : LetOrConst BindingList `;` - 1. Perform ? Evaluation of |BindingList|. + 1. Perform ? BindingEvaluation of |BindingList| with parameter ~normal~. + 1. Return ~empty~. + + UsingDeclaration : `using` BindingList `;` + + 1. Perform ? BindingEvaluation of |BindingList| with parameter ~sync-dispose~. 1. Return ~empty~. +
    + + +

    + Runtime Semantics: BindingEvaluation ( + _hint_: either ~normal~ or ~sync-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 parameter _hint_. + 1. Return ? BindingEvaluation of |LexicalBinding| with parameter _hint_. LexicalBinding : BindingIdentifier + 1. Assert: _hint_ is ~normal~. 1. Let _lhs_ be ! ResolveBinding(StringValue of |BindingIdentifier|). - 1. Perform ! InitializeReferencedBinding(_lhs_, *undefined*). + 1. Perform ! InitializeReferencedBinding(_lhs_, *undefined*, ~normal~). 1. Return ~empty~. -

    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` or `using` declaration.

    LexicalBinding : BindingIdentifier Initializer @@ -21239,11 +21556,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. Perform ! InitializeReferencedBinding(_lhs_, _value_, _hint_). 1. Return ~empty~.
    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 +21727,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 +21764,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 +22085,14 @@

    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_, _forDecl_)). 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_, _bodyResult_)). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return ? _bodyResult_. @@ -21838,21 +22158,22 @@

    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, ~Using] `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, ~Using] `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, ~Using] `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, ~Using] + [+Using] `using` [no LineTerminator here] [lookahead != `await`] ForBinding[?Yield, ?Await, +Using] - ForBinding[Yield, Await] : + ForBinding[Yield, Await, Using] : BindingIdentifier[?Yield, ?Await] - BindingPattern[?Yield, ?Await] + [~Using] BindingPattern[?Yield, ?Await]

    This section is extended by Annex .

    @@ -21994,6 +22315,12 @@

    1. Perform ! _environment_.CreateMutableBinding(_name_, *false*). 1. Return ~unused~. + ForDeclaration : `using` ForBinding + + 1. Assert: _environment_ is a declarative Environment Record. + 1. For each element _name_ of the BoundNames of |ForBinding|, do + 1. Perform ! _environment_.CreateImmutableBinding(_name_, *true*). + @@ -22139,6 +22466,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 +22479,12 @@

    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. If IsUsingDeclaration of _lhs_ is *true*, then + 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~sync-dispose~)). + 1. Else, + 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~normal~)). 1. If _status_ is an abrupt completion, then + 1. Set _status_ to Completion(DisposeResources(_iterationEnv_, _status_)). 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 +22493,7 @@

    1. Assert: _iterationKind_ is ~iterate~. 1. Return ? IteratorClose(_iteratorRecord_, _status_). 1. Let _result_ be Completion(Evaluation of _stmt_). + 1. Set _result_ to Completion(DisposeResources(_iterationEnv_, _stmt_)). 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 +22984,7 @@

    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_, _R_)). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return _R_. @@ -23343,7 +23677,9 @@

    FunctionBody : FunctionStatementList 1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). - 1. Return ? Evaluation of |FunctionStatementList|. + 1. Let _result_ be Completion(Evaluation of |FunctionStatementList|). + 1. Let _env_ be the running execution context's LexicalEnvironment. + 1. Return ? DisposeResources(_env_, _result_). @@ -23409,7 +23745,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_. @@ -23957,7 +24293,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 +24528,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 +25067,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_, _result_). @@ -24887,7 +25225,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 +25441,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_. @@ -25336,6 +25674,7 @@

    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 +25763,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 +25777,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_. @@ -25652,6 +25995,60 @@

    + +

    Static Semantics: HasInterminatedUsingDeclaration ( ): 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*. + + + LexicalDeclaration : UsingDeclaration + + 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| with argument _call_. + + + + CaseClause : + `case` Expression `:` StatementList? + + DefaultClause : + `default` `:` StatementList? + + + 1. If |StatementList| is present, return HasUnterminatedUsingDeclaration of |StatementList|. + +
    + +

    PrepareForTailCall ( ): ~unused~

    @@ -27926,14 +28323,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 +28350,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 +28362,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 +28385,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_, _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 +28700,7 @@

    Syntax

    `export` ExportFromClause FromClause `;` `export` NamedExports `;` `export` VariableStatement[~Yield, +Await] - `export` Declaration[~Yield, +Await] + `export` [lookahead != `using`] 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 +29398,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 +29409,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 +31197,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 +31283,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 +31399,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 +31476,84 @@

    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_ [ , _options_ ] )

    +

    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 _msg_ be ? ToString(_message_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"message"*, _msg_). + 1. Perform ? InstallErrorCause(_O_, _options_). + 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.

    @@ -45890,6 +46366,19 @@

    %IteratorPrototype% [ @@iterator ] ( )

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

    + + +

    %IteratorPrototype% [ @@dispose ] ( )

    +

    The following steps are taken:

    + + 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]"*.

    +
    @@ -46078,6 +46567,246 @@

    + +

    Resource Management

    + + +

    Common Resource Management Interfaces

    + + +

    The Disposable Interface

    +

    The Disposable interface includes the property described in :

    + + + + + + + + + + + + + + +
    + Property + + Value + + Requirements +
    + `@@dispose` + + A function. + +

    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.

    +
    +
    +
    + +
    +
    + + +

    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 ( )

    +

    When the `DisposableStack` function is called, the following steps are taken:

    + + 1. If NewTarget is *undefined*, throw a *TypeError* exception. + 1. Let _disposableStack_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposableResourceStack]] »). + 1. Set _disposableStack_.[[DisposableState]] to ~pending~. + 1. Set _disposableStack_.[[DisposableResourceStack]] to a new empty List. + 1. Return _disposableStack_. + +
    +
    + + +

    Properties of the DisposableStack Constructor

    +

    The DisposableStack constructor:

    +
      +
    • Has a [[Prototype]] internal slot whose value is %Function.prototype%.
    • +
    +
    + + +

    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.
    • +
    + + +

    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:

    + + 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.dispose ()

    +

    When the `dispose` method is called, the following steps are taken:

    + + 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_, NormalCompletion(*undefined*)). + +
    + + +

    DisposableStack.prototype.use( _value_ )

    +

    When the `use` function is called with one argument, the following steps are taken:

    + + 1. Let _disposableStack_ be the *this* value. + 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). + 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception. + 1. If _value_ is neither *null* nor *undefined*, then + 1. If Type(_value_) is not Object, throw a *TypeError* exception. + 1. Let _method_ be GetDisposeMethod(_value_, ~sync-dispose~). + 1. If _method_ is *undefined*, then + 1. Throw a *TypeError* exception. + 1. Else, + 1. Perform ? AddDisposableResource(_disposableStack_, _value_, ~sync-dispose~, _method_). + 1. Return _value_. + +
    + + +

    DisposableStack.prototype.adopt( _value_, _onDispose_ )

    +

    When the `adopt` function is called with two arguments, the following steps are taken:

    + + 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 _F_ be a new built-in function object as defined in . + 1. Set _F_.[[Argument]] to _value_. + 1. Set _F_.[[OnDisposeCallback]] to _onDispose_. + 1. Perform ? AddDisposableResource(_disposableStack_, *undefined*, ~sync-dispose~, _F_). + 1. Return _value_. + + + +

    DisposableStack Adopt Callback Functions

    +

    A DisposableStack adopt callback function is an anonymous built-in function object that has [[Argument]] and [[OnDisposeCallback]] internal slots.

    +

    When a DisposableStack adopt callback function is called, the following steps are taken:

    + + 1. Let _F_ be the active function object. + 1. Assert: IsCallable(_F_.[[OnDisposeCallback]]) is *true*. + 1. Return Call(_F_.[[OnDisposeCallback]], *undefined*, « _F_.[[Argument]] »). + +
    +
    + + +

    DisposableStack.prototype.defer( _onDispose_ )

    +

    When the `defer` function is called with one argument, the following steps are taken:

    + + 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_, *undefined*, ~sync-dispose~, _onDispose_). + 1. Return *undefined*. + +
    + + +

    DisposableStack.prototype.move()

    +

    When the `move` function is called, the following steps are taken:

    + + 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]], [[DisposableResourceStack]] »). + 1. Set _newDisposableStack_.[[DisposableState]] to ~pending~. + 1. Set _newDisposableStack_.[[DisposableResourceStack]] to _disposableStack_.[[DisposableResourceStack]]. + 1. Set _disposableStack_.[[DisposableResourceStack]] to a new empty List. + 1. Set _disposableStack_.[[DisposableState]] to ~disposed~. + 1. Return _newDisposableStack_. + +
    + + +

    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 + + Description +
    + [[DisposableState]] + + One of ~pending~ or ~disposed~. Governs how a disposable stack will react to incoming calls to its `@@dispose` method. +
    + [[DisposableResourceStack]] + + A List of DisposableResource Records. +
    +
    +
    +
    +

    Promise Objects

    A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.

    @@ -47520,12 +48249,14 @@

    1. Set the Generator component of _genContext_ to _generator_. 1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ and performs the following steps when called: 1. Let _acGenContext_ be the running execution context. + 1. Let _env_ be _acGenContext_'s LexicalEnvironment. 1. Let _acGenerator_ be the Generator component of _acGenContext_. 1. If _generatorBody_ is a Parse Node, then 1. Let _result_ be Completion(Evaluation of _generatorBody_). 1. Else, 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. 1. Let _result_ be _generatorBody_(). + 1. Set _result_ to Completion(DisposeResources(_env_, _result_)). 1. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return. 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. Set _acGenerator_.[[GeneratorState]] to ~completed~. @@ -47877,12 +48608,14 @@

    1. Set the Generator component of _genContext_ to _generator_. 1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ and performs the following steps when called: 1. Let _acGenContext_ be the running execution context. + 1. Let _env_ be _acGenContext_'s LexicalEnvironment. 1. Let _acGenerator_ be the Generator component of _acGenContext_. 1. If _generatorBody_ is a Parse Node, then 1. Let _result_ be Completion(Evaluation of _generatorBody_). 1. Else, 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. 1. Let _result_ be Completion(_generatorBody_()). + 1. Set _result_ to Completion(DisposeResources(_env_, _result_)). 1. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return. 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. Set _acGenerator_.[[AsyncGeneratorState]] to ~completed~. @@ -48266,7 +48999,9 @@

    1. Let _runningContext_ be the running execution context. 1. Let _closure_ be a new Abstract Closure with no parameters that captures _promiseCapability_ and _asyncBody_ and performs the following steps when called: 1. Let _acAsyncContext_ be the running execution context. + 1. Let _env_ be _acAsyncContext_'s LexicalEnvironment. 1. Let _result_ be Completion(Evaluation of _asyncBody_). + 1. Set _result_ to Completion(DisposeResources(_env_, _result_)). 1. Assert: If we return here, the async function either threw an exception or performed an implicit or explicit return; all awaiting is done. 1. Remove _acAsyncContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. If _result_ is a normal completion, then @@ -50559,7 +51294,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*). From ecbb4233821df03f4897c9b22cd5be916c84f57d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 18:00:23 -0500 Subject: [PATCH 02/56] Fix lint errors --- spec.html | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/spec.html b/spec.html index 1e6ad487a1..95f3c69d5f 100644 --- a/spec.html +++ b/spec.html @@ -7246,7 +7246,7 @@

    - 1. If _method_ is not present then, + 1. If _method_ is not present, then 1. If _V_ is *null* or *undefined*, return NormalCompletion(~empty~). 1. If Type(_V_) is not Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_). @@ -7328,19 +7328,19 @@

    1. If _disposable_ is not *undefined*, then - 1. For each _resource_ of _disposable_.[[DisposableResourceStack]], in reverse list order, do + 1. For each element _resource_ of _disposable_.[[DisposableResourceStack]], in reverse list order, do 1. Let _result_ be Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]]). 1. If _result_.[[Type]] is ~throw~, then 1. If _completion_.[[Type]] is ~throw~, 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. 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. Return _completion_. + 1. Set _completion_ to Completion(_result_). + 1. Return Completion(_completion_). @@ -21514,12 +21514,12 @@

    Static Semantics: Early Errors

    Runtime Semantics: Evaluation

    LexicalDeclaration : LetOrConst BindingList `;` - 1. Perform ? BindingEvaluation of |BindingList| with parameter ~normal~. + 1. Perform ? BindingEvaluation of |BindingList| with argument ~normal~. 1. Return ~empty~. UsingDeclaration : `using` BindingList `;` - 1. Perform ? BindingEvaluation of |BindingList| with parameter ~sync-dispose~. + 1. Perform ? BindingEvaluation of |BindingList| with argument ~sync-dispose~. 1. Return ~empty~. @@ -21534,8 +21534,8 @@

    BindingList : BindingList `,` LexicalBinding - 1. Perform ? BindingEvaluation of |BindingList| with parameter _hint_. - 1. Return ? BindingEvaluation of |LexicalBinding| with parameter _hint_. + 1. Perform ? BindingEvaluation of |BindingList| with argument _hint_. + 1. Return ? BindingEvaluation of |LexicalBinding| with argument _hint_. LexicalBinding : BindingIdentifier @@ -22085,7 +22085,7 @@

    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_, _forDecl_)). + 1. Set _forDcl_ to Completion(DisposeResources(_loopEnv_, _forDcl_)). 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. @@ -26033,7 +26033,7 @@

    Static Semantics: HasInterminatedUsingDeclaration ( ): a Boolean

    1. Let _has_ be HasUnterminatedUsingDeclaration of |CaseClauses|. 1. If _has_ is *true*, return *true*. - 1. Return HasUnterminatedUsingDeclaration of |CaseClause| with argument _call_. + 1. Return HasUnterminatedUsingDeclaration of |CaseClause|. @@ -26047,7 +26047,6 @@

    Static Semantics: HasInterminatedUsingDeclaration ( ): a Boolean

    1. If |StatementList| is present, return HasUnterminatedUsingDeclaration of |StatementList|.
    -

    PrepareForTailCall ( ): ~unused~

    @@ -31503,8 +31502,8 @@

    SuppressedError ( _error_, _suppressed_, _message_ [ , _options_ ] )

    1. Let _msg_ be ? ToString(_message_). 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"message"*, _msg_). 1. Perform ? InstallErrorCause(_O_, _options_). - 1. Perform ! CreateNonEnumerableDataPropertyOrThrow(_O_, *"error"*, _error_). - 1. Perform ! CreateNonEnumerableDataPropertyOrThrow(_O_, *"suppressed"*, _suppressed_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"error"*, _error_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"suppressed"*, _suppressed_). 1. Return _O_.
    @@ -46607,7 +46606,6 @@

    The Disposable Interface

    - @@ -46674,19 +46672,19 @@

    get DisposableStack.prototype.disposed

    -

    DisposableStack.prototype.dispose ()

    +

    DisposableStack.prototype.dispose ( )

    When the `dispose` method is called, the following steps are taken:

    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_, NormalCompletion(*undefined*)). + 1. Return ? DisposeResources(_disposableStack_, NormalCompletion(*undefined*)).
    -

    DisposableStack.prototype.use( _value_ )

    +

    DisposableStack.prototype.use ( _value_ )

    When the `use` function is called with one argument, the following steps are taken:

    1. Let _disposableStack_ be the *this* value. @@ -46704,7 +46702,7 @@

    DisposableStack.prototype.use( _value_ )

    -

    DisposableStack.prototype.adopt( _value_, _onDispose_ )

    +

    DisposableStack.prototype.adopt ( _value_, _onDispose_ )

    When the `adopt` function is called with two arguments, the following steps are taken:

    1. Let _disposableStack_ be the *this* value. @@ -46725,13 +46723,13 @@

    DisposableStack Adopt Callback Functions

    1. Let _F_ be the active function object. 1. Assert: IsCallable(_F_.[[OnDisposeCallback]]) is *true*. - 1. Return Call(_F_.[[OnDisposeCallback]], *undefined*, « _F_.[[Argument]] »). + 1. Return ? Call(_F_.[[OnDisposeCallback]], *undefined*, « _F_.[[Argument]] »).
    -

    DisposableStack.prototype.defer( _onDispose_ )

    +

    DisposableStack.prototype.defer ( _onDispose_ )

    When the `defer` function is called with one argument, the following steps are taken:

    1. Let _disposableStack_ be the *this* value. @@ -46744,7 +46742,7 @@

    DisposableStack.prototype.defer( _onDispose_ )

    -

    DisposableStack.prototype.move()

    +

    DisposableStack.prototype.move ( )

    When the `move` function is called, the following steps are taken:

    1. Let _disposableStack_ be the *this* value. @@ -46760,7 +46758,7 @@

    DisposableStack.prototype.move()

    -

    DisposableStack.prototype [ @@dispose ] ()

    +

    DisposableStack.prototype [ @@dispose ] ( )

    The initial value of the @@dispose property is %DisposableStack.prototype.dispose%, defined in .

    From ab4c487c5139ef558b960b2b229f23b1895f1d21 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 18:02:27 -0500 Subject: [PATCH 03/56] Run formatter --- spec.html | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/spec.html b/spec.html index 95f3c69d5f..95e7506db2 100644 --- a/spec.html +++ b/spec.html @@ -7175,13 +7175,13 @@

    Operations on Disposable Objects

    See Common Resource Management Interfaces ().

    +

    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 @@ -7226,7 +7226,6 @@

    DisposableResource Records

    A function object that will be called with [[ResourceValue]] as its *this* value when the resource disposed.
    @@ -7237,10 +7236,10 @@

    DisposableResource Records

    AddDisposableResource ( - _disposable_ : an object with a [[DisposableResourceStack]] internal slot, - _V_ : an ECMAScript language value, - _hint_ : ~sync-dispose~, - optional _method_ : a function object, + _disposable_: an object with a [[DisposableResourceStack]] internal slot, + _V_: an ECMAScript language value, + _hint_: ~sync-dispose~, + optional _method_: a function object, )

    @@ -7267,9 +7266,9 @@

    CreateDisposableResource ( - _V_ : an Object or *undefined*, - _hint_ : ~sync-dispose~, - optional _method_ : a function object, + _V_: an Object or *undefined*, + _hint_: ~sync-dispose~, + optional _method_: a function object, )

    @@ -7290,8 +7289,8 @@

    GetDisposeMethod ( - _V_ : an Object, - _hint_ : ~sync-dispose~, + _V_: an Object, + _hint_: ~sync-dispose~, )

    @@ -7305,9 +7304,9 @@

    Dispose ( - _V_ : an Object or *undefined*, - _hint_ : ~sync-dispose~, - _method_ : a function object, + _V_: an Object or *undefined*, + _hint_: ~sync-dispose~, + _method_: a function object, )

    @@ -7321,8 +7320,8 @@

    DisposeResources ( - _disposable_ : an object with a [[DisposableResourceStack]] internal slot or *undefined*, - _completion_ : a Completion Record, + _disposable_: an object with a [[DisposableResourceStack]] internal slot or *undefined*, + _completion_: a Completion Record, ): a Completion Record

    @@ -21528,7 +21527,7 @@

    Runtime Semantics: Evaluation

    Runtime Semantics: BindingEvaluation ( _hint_: either ~normal~ or ~sync-dispose~, - ) : either a normal completion containing ~unused~ or an abrupt completion + ): either a normal completion containing ~unused~ or an abrupt completion

    @@ -46373,7 +46372,7 @@

    %IteratorPrototype% [ @@dispose ] ( )

    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. Perform ? Call(_return_, _O_, « »). 1. Return NormalCompletion(~empty~).

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

    @@ -46575,9 +46574,8 @@

    Common Resource Management Interfaces

    The Disposable Interface

    The Disposable interface includes the property described in :

    - + - -
    Property @@ -46602,7 +46600,6 @@

    The Disposable Interface

    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.

    @@ -46634,7 +46631,7 @@

    DisposableStack ( )

    When the `DisposableStack` function is called, the following steps are taken:

    1. If NewTarget is *undefined*, throw a *TypeError* exception. - 1. Let _disposableStack_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposableResourceStack]] »). + 1. Let _disposableStack_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposableResourceStack]] »). 1. Set _disposableStack_.[[DisposableState]] to ~pending~. 1. Set _disposableStack_.[[DisposableResourceStack]] to a new empty List. 1. Return _disposableStack_. @@ -46694,7 +46691,7 @@

    DisposableStack.prototype.use ( _value_ )

    1. If Type(_value_) is not Object, throw a *TypeError* exception. 1. Let _method_ be GetDisposeMethod(_value_, ~sync-dispose~). 1. If _method_ is *undefined*, then - 1. Throw a *TypeError* exception. + 1. Throw a *TypeError* exception. 1. Else, 1. Perform ? AddDisposableResource(_disposableStack_, _value_, ~sync-dispose~, _method_). 1. Return _value_. @@ -46723,7 +46720,7 @@

    DisposableStack Adopt Callback Functions

    1. Let _F_ be the active function object. 1. Assert: IsCallable(_F_.[[OnDisposeCallback]]) is *true*. - 1. Return ? Call(_F_.[[OnDisposeCallback]], *undefined*, « _F_.[[Argument]] »). + 1. Return ? Call(_F_.[[OnDisposeCallback]], *undefined*, « _F_.[[Argument]] »).
    @@ -46748,7 +46745,7 @@

    DisposableStack.prototype.move ( )

    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]], [[DisposableResourceStack]] »). + 1. Let _newDisposableStack_ be ? OrdinaryCreateFromConstructor(%DisposableStack%, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposableResourceStack]] »). 1. Set _newDisposableStack_.[[DisposableState]] to ~pending~. 1. Set _newDisposableStack_.[[DisposableResourceStack]] to _disposableStack_.[[DisposableResourceStack]]. 1. Set _disposableStack_.[[DisposableResourceStack]] to a new empty List. @@ -46774,7 +46771,6 @@

    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 @@ -46799,7 +46795,6 @@

    Properties of DisposableStack Instances

    A List of DisposableResource Records.
    From 4fce288a2cf635ce8221993ce40bf09c49303184 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 18:30:13 -0500 Subject: [PATCH 04/56] Fix signature for DisposeResources --- spec.html | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/spec.html b/spec.html index 95e7506db2..3d2f25a8a4 100644 --- a/spec.html +++ b/spec.html @@ -7322,7 +7322,7 @@

    DisposeResources ( _disposable_: an object with a [[DisposableResourceStack]] internal slot or *undefined*, _completion_: a Completion Record, - ): a Completion Record + ): either a normal completion containing an ECMAScript language value or an abrupt completion

    @@ -9780,7 +9780,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_). @@ -10378,7 +10378,7 @@

    _N_: a String, _V_: an ECMAScript language value, _hint_: either ~normal~ or ~sync-dispose~, - ): a normal completion containing ~unused~ + ): either a normal completion containing ~unused~ or a throw completion

    for
    @@ -10415,7 +10415,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 @@ -11142,11 +11142,11 @@

    1. Let _DclRec_ be _envRec_.[[DeclarativeRecord]]. 1. If ! _DclRec_.HasBinding(_N_) is *true*, then - 1. Return ! _DclRec_.InitializeBinding(_N_, _V_, _hint_). + 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~). @@ -11408,7 +11408,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~. @@ -21541,7 +21541,7 @@

    1. Assert: _hint_ is ~normal~. 1. Let _lhs_ be ! ResolveBinding(StringValue of |BindingIdentifier|). 1. Perform ! InitializeReferencedBinding(_lhs_, *undefined*, ~normal~). - 1. Return ~empty~. + 1. Return ~unused~.

    A static semantics rule ensures that this form of |LexicalBinding| never occurs in a `const` or `using` declaration.

    @@ -21556,7 +21556,7 @@

    1. Let _rhs_ be ? Evaluation of |Initializer|. 1. Let _value_ be ? GetValue(_rhs_). 1. Perform ! InitializeReferencedBinding(_lhs_, _value_, _hint_). - 1. Return ~empty~. + 1. Return ~unused~. LexicalBinding : BindingPattern Initializer @@ -22144,7 +22144,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~. @@ -51167,7 +51167,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. @@ -51237,7 +51237,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. From 2fa4817e432e506239bd031b519df7664ff9244f Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 18:43:01 -0500 Subject: [PATCH 05/56] Fixes for some esmeta warnings --- spec.html | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/spec.html b/spec.html index 3d2f25a8a4..a200274680 100644 --- a/spec.html +++ b/spec.html @@ -7240,7 +7240,7 @@

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

    @@ -7269,9 +7269,10 @@

    _V_: an Object or *undefined*, _hint_: ~sync-dispose~, optional _method_: a function object, - ) + ): either a DisposableResource Record or a throw completion

    -
    +
    +
    1. If _method_ is not present, then 1. If _V_ is *undefined*, throw a *TypeError* exception. @@ -7291,9 +7292,10 @@

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

    -
    +
    +
    1. Assert: _hint_ is ~sync-dispose~. 1. Let _method_ be ? GetMethod(_V_, @@dispose). @@ -7307,9 +7309,10 @@

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

    -
    +
    +
    1. Assert: _hint_ is ~sync-dispose~. 1. Perform ? Call(_method_, _V_). @@ -7321,14 +7324,15 @@

    DisposeResources ( _disposable_: an object with a [[DisposableResourceStack]] internal slot or *undefined*, - _completion_: a Completion Record, + _completion_: either a normal completion containing an ECMAScript language value or an abrupt completion, ): either a normal completion containing an ECMAScript language value or an abrupt completion

    -
    +
    +
    1. If _disposable_ is not *undefined*, then 1. For each element _resource_ of _disposable_.[[DisposableResourceStack]], in reverse list order, do - 1. Let _result_ be Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]]). + 1. Let _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). 1. If _result_.[[Type]] is ~throw~, then 1. If _completion_.[[Type]] is ~throw~, then 1. Set _result_ to _result_.[[Value]]. @@ -7338,7 +7342,7 @@

    1. Perform CreateNonEnumerableDataPropertyOrThrow(_error_, *"suppressed"*, _suppressed_). 1. Set _completion_ to ThrowCompletion(_error_). 1. Else, - 1. Set _completion_ to Completion(_result_). + 1. Set _completion_ to _result_. 1. Return Completion(_completion_). @@ -22492,7 +22496,7 @@

    1. Assert: _iterationKind_ is ~iterate~. 1. Return ? IteratorClose(_iteratorRecord_, _status_). 1. Let _result_ be Completion(Evaluation of _stmt_). - 1. Set _result_ to Completion(DisposeResources(_iterationEnv_, _stmt_)). + 1. Set _result_ to Completion(DisposeResources(_iterationEnv_, _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 From d6fa449cb5bff65498cd552ef2f85d6e03b2037a Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 18:48:50 -0500 Subject: [PATCH 06/56] Fixes for some esmeta warnings --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index a200274680..e3ce3420f7 100644 --- a/spec.html +++ b/spec.html @@ -7309,7 +7309,7 @@

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

    From 3de7dfbcf43ff74c57d7038c1a75b30a99155e5c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 18:52:00 -0500 Subject: [PATCH 07/56] Add missing ReturnIfAbrupt in DisposableStack.prototype.use --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index e3ce3420f7..d1bf6b82b6 100644 --- a/spec.html +++ b/spec.html @@ -46693,7 +46693,7 @@

    DisposableStack.prototype.use ( _value_ )

    1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception. 1. If _value_ is neither *null* nor *undefined*, then 1. If Type(_value_) is not Object, throw a *TypeError* exception. - 1. Let _method_ be GetDisposeMethod(_value_, ~sync-dispose~). + 1. Let _method_ be ? GetDisposeMethod(_value_, ~sync-dispose~). 1. If _method_ is *undefined*, then 1. Throw a *TypeError* exception. 1. Else, From 290b082b486f8d1e7aba35dfdf34f4b6e84d6682 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 18:57:36 -0500 Subject: [PATCH 08/56] More ecmarkup signature fixes --- spec.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec.html b/spec.html index d1bf6b82b6..8965cf5585 100644 --- a/spec.html +++ b/spec.html @@ -7240,13 +7240,13 @@

    _V_: an ECMAScript language value, _hint_: ~sync-dispose~, optional _method_: a function object, - ): either a normal completion containing ~empty~ or a throw completion + ): either a normal completion containing ~unused~ or a throw completion

    1. If _method_ is not present, then - 1. If _V_ is *null* or *undefined*, return NormalCompletion(~empty~). + 1. If _V_ is *null* or *undefined*, return ~unused~. 1. If Type(_V_) is not Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_). 1. Else, @@ -7256,7 +7256,7 @@

    1. If Type(_V_) is not Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_, _method_). 1. Append _resource_ to _disposable_.[[DisposableResourceStack]]. - 1. Return NormalCompletion(~empty~). + 1. Return ~unused~. Currently, the only allowed value for _hint_ is ~sync-dispose~. @@ -7269,7 +7269,7 @@

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

    From 75a5fa54dd4617697d472ff20a5225b309879767 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Jan 2023 19:08:37 -0500 Subject: [PATCH 09/56] Change DisposeResources signature to return completion record --- spec.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec.html b/spec.html index 8965cf5585..8307588063 100644 --- a/spec.html +++ b/spec.html @@ -7324,8 +7324,8 @@

    DisposeResources ( _disposable_: an object with a [[DisposableResourceStack]] internal slot or *undefined*, - _completion_: either a normal completion containing an ECMAScript language value or an abrupt completion, - ): either a normal completion containing an ECMAScript language value or an abrupt completion + _completion_: a Completion Record, + ): a Completion Record

    @@ -7343,7 +7343,7 @@

    1. Set _completion_ to ThrowCompletion(_error_). 1. Else, 1. Set _completion_ to _result_. - 1. Return Completion(_completion_). + 1. Return ? _completion_. From 81da84d6ba5b2fc61aeefe6d064f087ae7d3e37e Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:39:40 -0500 Subject: [PATCH 10/56] Order sections by property name --- spec.html | 100 +++++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/spec.html b/spec.html index 8307588063..9939d8376c 100644 --- a/spec.html +++ b/spec.html @@ -46360,15 +46360,6 @@

    The %IteratorPrototype% Object

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

    %IteratorPrototype% [ @@iterator ] ( )

    -

    This function performs the following steps when called:

    - - 1. Return the *this* value. - -

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

    -
    -

    %IteratorPrototype% [ @@dispose ] ( )

    The following steps are taken:

    @@ -46381,6 +46372,15 @@

    %IteratorPrototype% [ @@dispose ] ( )

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

    + + +

    %IteratorPrototype% [ @@iterator ] ( )

    +

    This function performs the following steps when called:

    + + 1. Return the *this* value. + +

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

    +
    @@ -46661,47 +46661,6 @@

    Properties of the DisposableStack Prototype Object

  • does not have a [[DisposableState]] internal slot or any of the other internal slots of DisposableStack instances.
- -

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:

- - 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.dispose ( )

-

When the `dispose` method is called, the following steps are taken:

- - 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_, NormalCompletion(*undefined*)). - -
- - -

DisposableStack.prototype.use ( _value_ )

-

When the `use` function is called with one argument, the following steps are taken:

- - 1. Let _disposableStack_ be the *this* value. - 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). - 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception. - 1. If _value_ is neither *null* nor *undefined*, then - 1. If Type(_value_) is not Object, throw a *TypeError* exception. - 1. Let _method_ be ? GetDisposeMethod(_value_, ~sync-dispose~). - 1. If _method_ is *undefined*, then - 1. Throw a *TypeError* exception. - 1. Else, - 1. Perform ? AddDisposableResource(_disposableStack_, _value_, ~sync-dispose~, _method_). - 1. Return _value_. - -
-

DisposableStack.prototype.adopt ( _value_, _onDispose_ )

When the `adopt` function is called with two arguments, the following steps are taken:

@@ -46742,6 +46701,29 @@

DisposableStack.prototype.defer ( _onDispose_ )

+ +

DisposableStack.prototype.dispose ( )

+

When the `dispose` method is called, the following steps are taken:

+ + 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_, 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:

+ + 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 ( )

When the `move` function is called, the following steps are taken:

@@ -46758,6 +46740,24 @@

DisposableStack.prototype.move ( )

+ +

DisposableStack.prototype.use ( _value_ )

+

When the `use` function is called with one argument, the following steps are taken:

+ + 1. Let _disposableStack_ be the *this* value. + 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). + 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception. + 1. If _value_ is neither *null* nor *undefined*, then + 1. If Type(_value_) is not Object, throw a *TypeError* exception. + 1. Let _method_ be ? GetDisposeMethod(_value_, ~sync-dispose~). + 1. If _method_ is *undefined*, then + 1. Throw a *TypeError* exception. + 1. Else, + 1. Perform ? AddDisposableResource(_disposableStack_, _value_, ~sync-dispose~, _method_). + 1. Return _value_. + +
+

DisposableStack.prototype [ @@dispose ] ( )

The initial value of the @@dispose property is %DisposableStack.prototype.dispose%, defined in .

From 262c6aa9774b065f05e803bf23d391b24adcec09 Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:42:44 -0500 Subject: [PATCH 11/56] Syntax of types --- spec.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec.html b/spec.html index 9939d8376c..79fae6c85f 100644 --- a/spec.html +++ b/spec.html @@ -7198,7 +7198,7 @@

DisposableResource Records

[[ResourceValue]] - An Object or *undefined*. + an Object or *undefined* The value to be disposed. @@ -7209,7 +7209,7 @@

DisposableResource Records

[[Hint]] - ~sync-dispose~. + ~sync-dispose~ Indicates that the resource was added by a `using` declaration or DisposableStack object. @@ -7220,7 +7220,7 @@

DisposableResource Records

[[DisposeMethod]] - A function object. + a function object A function object that will be called with [[ResourceValue]] as its *this* value when the resource disposed. @@ -7236,7 +7236,7 @@

DisposableResource Records

AddDisposableResource ( - _disposable_: an object with a [[DisposableResourceStack]] internal slot, + _disposable_: an Object that has a [[DisposableResourceStack]] internal slot, _V_: an ECMAScript language value, _hint_: ~sync-dispose~, optional _method_: a function object, @@ -7309,7 +7309,7 @@

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

@@ -7323,7 +7323,7 @@

DisposeResources ( - _disposable_: an object with a [[DisposableResourceStack]] internal slot or *undefined*, + _disposable_: an Object that has a [[DisposableResourceStack]] internal slot or *undefined*, _completion_: a Completion Record, ): a Completion Record

@@ -22320,7 +22320,7 @@

ForDeclaration : `using` ForBinding - 1. Assert: _environment_ is a declarative Environment Record. + 1. Assert: _environment_ is a Declarative Environment Record. 1. For each element _name_ of the BoundNames of |ForBinding|, do 1. Perform ! _environment_.CreateImmutableBinding(_name_, *true*). @@ -46596,7 +46596,7 @@

The Disposable Interface

`@@dispose` - A function. + 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.

From 44f8c22469e594cb38238d703a2963fb59f1c009 Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:43:46 -0500 Subject: [PATCH 12/56] id of AO clause doesn't need to include param names --- spec.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 79fae6c85f..ac76797691 100644 --- a/spec.html +++ b/spec.html @@ -7233,7 +7233,7 @@

DisposableResource Records

- +

AddDisposableResource ( _disposable_: an Object that has a [[DisposableResourceStack]] internal slot, @@ -7320,7 +7320,7 @@

- +

DisposeResources ( _disposable_: an Object that has a [[DisposableResourceStack]] internal slot or *undefined*, From c24dfd04704646836943b7599fda78ed1160e4a8 Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:45:34 -0500 Subject: [PATCH 13/56] Avoid the use of `Type()` --- spec.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec.html b/spec.html index ac76797691..d6145125e5 100644 --- a/spec.html +++ b/spec.html @@ -7247,13 +7247,13 @@

1. If _method_ is not present, then 1. If _V_ is *null* or *undefined*, return ~unused~. - 1. If Type(_V_) is not Object, throw a *TypeError* exception. + 1. If _V_ is not an Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_). 1. Else, 1. If _V_ is *null* or *undefined*, then 1. Let _resource_ be ? CreateDisposableResource(*undefined*, _hint_, _method_). 1. Else, - 1. If Type(_V_) is not Object, throw a *TypeError* exception. + 1. If _V_ is not an Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_, _method_). 1. Append _resource_ to _disposable_.[[DisposableResourceStack]]. 1. Return ~unused~. @@ -46748,7 +46748,7 @@

DisposableStack.prototype.use ( _value_ )

1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception. 1. If _value_ is neither *null* nor *undefined*, then - 1. If Type(_value_) is not Object, throw a *TypeError* exception. + 1. If _value_ is not an Object, throw a *TypeError* exception. 1. Let _method_ be ? GetDisposeMethod(_value_, ~sync-dispose~). 1. If _method_ is *undefined*, then 1. Throw a *TypeError* exception. From 04b95ea9db4ce393b8d3bffa35a4ad34f0fc3c8f Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:46:39 -0500 Subject: [PATCH 14/56] Use preamble conventions from PR #2592 --- spec.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec.html b/spec.html index d6145125e5..da58ec578c 100644 --- a/spec.html +++ b/spec.html @@ -46362,7 +46362,7 @@

The %IteratorPrototype% Object

%IteratorPrototype% [ @@dispose ] ( )

-

The following steps are taken:

+

This function performs the following steps when called:

1. Let _O_ be the *this* value. 1. Let _return_ be ? GetMethod(_O_, `"return"`). @@ -46632,7 +46632,7 @@

The DisposableStack Constructor

DisposableStack ( )

-

When the `DisposableStack` function is called, the following steps are taken:

+

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]], [[DisposableResourceStack]] »). @@ -46663,7 +46663,7 @@

Properties of the DisposableStack Prototype Object

DisposableStack.prototype.adopt ( _value_, _onDispose_ )

-

When the `adopt` function is called with two arguments, the following steps are taken:

+

This method performs the following steps when called:

1. Let _disposableStack_ be the *this* value. 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). @@ -46690,7 +46690,7 @@

DisposableStack Adopt Callback Functions

DisposableStack.prototype.defer ( _onDispose_ )

-

When the `defer` function is called with one argument, the following steps are taken:

+

This method performs the following steps when called:

1. Let _disposableStack_ be the *this* value. 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). @@ -46703,7 +46703,7 @@

DisposableStack.prototype.defer ( _onDispose_ )

DisposableStack.prototype.dispose ( )

-

When the `dispose` method is called, the following steps are taken:

+

This method performs the following steps when called:

1. Let _disposableStack_ be the *this* value. 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). @@ -46715,7 +46715,7 @@

DisposableStack.prototype.dispose ( )

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:

+

`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]]). @@ -46726,7 +46726,7 @@

get DisposableStack.prototype.disposed

DisposableStack.prototype.move ( )

-

When the `move` function is called, the following steps are taken:

+

This method performs the following steps when called:

1. Let _disposableStack_ be the *this* value. 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). @@ -46742,7 +46742,7 @@

DisposableStack.prototype.move ( )

DisposableStack.prototype.use ( _value_ )

-

When the `use` function is called with one argument, the following steps are taken:

+

This method performs the following steps when called:

1. Let _disposableStack_ be the *this* value. 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). From b77a7c29062493213f8e31e9bd6db4aa8f7f970c Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:48:01 -0500 Subject: [PATCH 15/56] Interface names are put in `` rather than `` --- spec.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec.html b/spec.html index da58ec578c..909e6e6967 100644 --- a/spec.html +++ b/spec.html @@ -46576,9 +46576,9 @@

Resource Management

Common Resource Management Interfaces

-

The Disposable Interface

-

The Disposable interface includes the property described in :

- +

The Disposable Interface

+

The Disposable interface includes the property described in :

+ + @@ -46788,7 +46791,10 @@

Properties of DisposableStack Instances

[[DisposableState]] + @@ -46796,7 +46802,10 @@

Properties of DisposableStack Instances

[[DisposableResourceStack]] +
From ebc69d366d5196a27823a8bc8cc6b165bb4e614c Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:49:17 -0500 Subject: [PATCH 16/56] A 'Slots' table should have a 'Type' column --- spec.html | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 909e6e6967..9807c84386 100644 --- a/spec.html +++ b/spec.html @@ -46779,6 +46779,9 @@

Properties of DisposableStack Instances

Internal Slot + Type + Description - One of ~pending~ or ~disposed~. Governs how a disposable stack will react to incoming calls to its `@@dispose` method. + ~pending~ or ~disposed~ + + Governs how a disposable stack will react to incoming calls to its `@@dispose` method.
- A List of DisposableResource Records. + a List of DisposableResource Records + + ?
From 5af1a9c72ce524405dcbba1f2f69e9128ba42246 Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:50:13 -0500 Subject: [PATCH 17/56] Add 'UsingDeclaration' to Annex A --- spec.html | 1 + 1 file changed, 1 insertion(+) diff --git a/spec.html b/spec.html index 9807c84386..a2d58492ff 100644 --- a/spec.html +++ b/spec.html @@ -50152,6 +50152,7 @@

Statements

+ From 28766d63ea6ad8524ec6e38aee98a4788023c5bd Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Mon, 23 Jan 2023 21:51:15 -0500 Subject: [PATCH 18/56] misc minor fixes --- spec.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec.html b/spec.html index a2d58492ff..c89891c60a 100644 --- a/spec.html +++ b/spec.html @@ -7331,7 +7331,7 @@

1. If _disposable_ is not *undefined*, then - 1. For each element _resource_ of _disposable_.[[DisposableResourceStack]], in reverse list order, do + 1. For each element _resource_ of _disposable_.[[DisposableResourceStack]], in reverse List order, do 1. Let _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). 1. If _result_.[[Type]] is ~throw~, then 1. If _completion_.[[Type]] is ~throw~, then @@ -25998,8 +25998,8 @@

- -

Static Semantics: HasInterminatedUsingDeclaration ( ): a Boolean

+ +

Static Semantics: HasUnterminatedUsingDeclaration ( ): a Boolean

StatementList : StatementList StatementListItem @@ -46365,7 +46365,7 @@

%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. Let _return_ be ? GetMethod(_O_, *"return"*). 1. If _return_ is not *undefined*, then 1. Perform ? Call(_return_, _O_, « »). 1. Return NormalCompletion(~empty~). @@ -46647,7 +46647,7 @@

DisposableStack ( )

Properties of the DisposableStack Constructor

The DisposableStack constructor:

    -
  • Has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • +
  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
From ccc4194f2fb8a54840b131dd9d334478fcda0977 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Jan 2023 14:05:03 -0500 Subject: [PATCH 19/56] add description suggestion from @jmdyck --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index c89891c60a..7c61489de7 100644 --- a/spec.html +++ b/spec.html @@ -46805,7 +46805,7 @@

Properties of DisposableStack Instances

a List of DisposableResource Records - ? + Resources to be disposed when the disposable stack is disposed. From 4883a6d43deb3e7d9e28689c92873c74ce5e47e7 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Jan 2023 16:13:52 -0500 Subject: [PATCH 20/56] Add DisposeCapabilityRecord from tc39/proposal-explicit-resource-management#144 --- esmeta-ignore.json | 2 - spec.html | 144 +++++++++++++++++++++++++++++---------------- 2 files changed, 92 insertions(+), 54 deletions(-) diff --git a/esmeta-ignore.json b/esmeta-ignore.json index dcb6101596..596be4c2e9 100644 --- a/esmeta-ignore.json +++ b/esmeta-ignore.json @@ -15,12 +15,10 @@ "BoundFunctionCreate", "Catch[0,0].CatchClauseEvaluation", "Catch[1,0].CatchClauseEvaluation", - "ClassStaticBlockBody[0,0].EvaluateClassStaticBlockBody", "CreateBuiltinFunction", "CreateMappedArgumentsObject", "CreateSharedByteDataBlock", "ForIn/OfBodyEvaluation", - "FunctionBody[0,0].EvaluateFunctionBody", "GeneratorBody[0,0].EvaluateGeneratorBody", "GetGlobalObject", "GetMethod", diff --git a/spec.html b/spec.html index 7c61489de7..39ec7a3369 100644 --- a/spec.html +++ b/spec.html @@ -7176,6 +7176,40 @@

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.

@@ -7233,13 +7267,25 @@

DisposableResource Records

+ +

+ NewDisposeCapability ( + ): a DisposeCapability Record +

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

AddDisposableResource ( - _disposable_: an Object that has a [[DisposableResourceStack]] internal slot, + _disposeCapability_: a DisposeCapability Record, _V_: an ECMAScript language value, _hint_: ~sync-dispose~, - optional _method_: a function object, + optional _method_: an ECMAScript language value, ): either a normal completion containing ~unused~ or a throw completion

@@ -7255,7 +7301,7 @@

1. Else, 1. If _V_ is not an Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_, _method_). - 1. Append _resource_ to _disposable_.[[DisposableResourceStack]]. + 1. Append _resource_ to _disposeCapability_.[[DisposableResourceStack]]. 1. Return ~unused~. @@ -7268,7 +7314,7 @@

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

@@ -7309,7 +7355,7 @@

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

@@ -7323,26 +7369,25 @@

DisposeResources ( - _disposable_: an Object that has a [[DisposableResourceStack]] internal slot or *undefined*, - _completion_: a Completion Record, - ): a Completion Record + _disposeCapability_: a DisposeCapability Record, + _completion_: either a normal completion containing an ECMAScript language value, or an abrupt completion, + ): either a normal completion containing an ECMAScript language value, or an abrupt completion

- 1. If _disposable_ is not *undefined*, then - 1. For each element _resource_ of _disposable_.[[DisposableResourceStack]], in reverse List order, do - 1. Let _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). - 1. If _result_.[[Type]] is ~throw~, then - 1. If _completion_.[[Type]] is ~throw~, 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. For each element _resource_ of _disposeCapability_.[[DisposableResourceStack]], in reverse List order, do + 1. Let _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). + 1. If _result_.[[Type]] is ~throw~, then + 1. If _completion_.[[Type]] is ~throw~, 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. Return ? _completion_.
@@ -10312,7 +10357,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 [[DisposableResourceStack]] field, which is a List of DisposableResource Records. This list is a stack of resources tracked by the `using` declarations that must be disposed when the Evaluation step that constructed the Environment Record has completed.

+

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 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.

@@ -10393,7 +10438,7 @@

1. Assert: _envRec_ must have an uninitialized binding for _N_. - 1. If _hint_ is not ~normal~, perform ? AddDisposableResource(_envRec_, _V_, _hint_). + 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~. @@ -11613,6 +11658,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_. @@ -21388,7 +21434,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_, _blockValue_)). + 1. Set _blockValue_ to Completion(DisposeResources(_blockEnv_.[[DisposeCapability]], UpdateEmpty(_blockValue_, *undefined*))). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return ? _blockValue_.
@@ -22088,14 +22134,14 @@

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_, _forDcl_)). + 1. Set _forDcl_ to Completion(DisposeResources(_loopEnv_.[[DisposeCapability]], _forDcl_)). 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_, _bodyResult_)). + 1. Set _bodyResult_ to Completion(DisposeResources(_loopEnv_.[[DisposeCapability]], _bodyResult_)). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return ? _bodyResult_. @@ -22487,7 +22533,7 @@

1. Else, 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~normal~)). 1. If _status_ is an abrupt completion, then - 1. Set _status_ to Completion(DisposeResources(_iterationEnv_, _status_)). + 1. Set _status_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], UpdateEmpty(_status_, *undefined*))). 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 @@ -22496,7 +22542,7 @@

1. Assert: _iterationKind_ is ~iterate~. 1. Return ? IteratorClose(_iteratorRecord_, _status_). 1. Let _result_ be Completion(Evaluation of _stmt_). - 1. Set _result_ to Completion(DisposeResources(_iterationEnv_, _result_)). + 1. Set _result_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], UpdateEmpty(_result_, *undefined*))). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. If LoopContinues(_result_, _labelSet_) is *false*, then 1. If _iterationKind_ is ~enumerate~, then @@ -22987,7 +23033,7 @@

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_, _R_)). + 1. Set _R_ to Completion(DisposeResources(_blockEnv_.[[DisposeCapability]], _R_)). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return _R_. @@ -23682,7 +23728,7 @@

1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). 1. Let _result_ be Completion(Evaluation of |FunctionStatementList|). 1. Let _env_ be the running execution context's LexicalEnvironment. - 1. Return ? DisposeResources(_env_, _result_). + 1. Return ? DisposeResources(_env_.[[DisposeCapability]], UpdateEmpty(_result_, *undefined*)). @@ -25072,7 +25118,7 @@

1. Perform ! FunctionDeclarationInstantiation(_functionObject_, « »). 1. Let _result_ be Completion(Evaluation of |ClassStaticBlockStatementList|). 1. Let _env_ be the running execution context's LexicalEnvironment. - 1. Return ? DisposeResources(_env_, _result_). + 1. Return ? DisposeResources(_env_.[[DisposeCapability]], UpdateEmpty(_result_, *undefined*)). @@ -28395,7 +28441,7 @@

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_, _result_)). + 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 @@ -46635,9 +46681,9 @@

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]], [[DisposableResourceStack]] »). + 1. Let _disposableStack_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposeCapability]] »). 1. Set _disposableStack_.[[DisposableState]] to ~pending~. - 1. Set _disposableStack_.[[DisposableResourceStack]] to a new empty List. + 1. Set _disposableStack_.[[DisposeCapability]] to NewDisposeCapability(). 1. Return _disposableStack_. @@ -46672,7 +46718,7 @@

DisposableStack.prototype.adopt ( _value_, _onDispose_ )

1. Let _F_ be a new built-in function object as defined in . 1. Set _F_.[[Argument]] to _value_. 1. Set _F_.[[OnDisposeCallback]] to _onDispose_. - 1. Perform ? AddDisposableResource(_disposableStack_, *undefined*, ~sync-dispose~, _F_). + 1. Perform ? AddDisposableResource(_disposableStack_.[[DisposeCapability]], *undefined*, ~sync-dispose~, _F_). 1. Return _value_. @@ -46696,7 +46742,7 @@

DisposableStack.prototype.defer ( _onDispose_ )

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_, *undefined*, ~sync-dispose~, _onDispose_). + 1. Perform ? AddDisposableResource(_disposableStack_.[[DisposeCapability]], *undefined*, ~sync-dispose~, _onDispose_). 1. Return *undefined*. @@ -46709,7 +46755,7 @@

DisposableStack.prototype.dispose ( )

1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). 1. If _disposableStack_.[[DisposableState]] is ~disposed~, return *undefined*. 1. Set _disposableStack_.[[DisposableState]] to ~disposed~. - 1. Return ? DisposeResources(_disposableStack_, NormalCompletion(*undefined*)). + 1. Return ? DisposeResources(_disposableStack_.[[DisposeCapability]], NormalCompletion(*undefined*)). @@ -46731,10 +46777,10 @@

DisposableStack.prototype.move ( )

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]], [[DisposableResourceStack]] »). + 1. Let _newDisposableStack_ be ? OrdinaryCreateFromConstructor(%DisposableStack%, *"%DisposableStack.prototype%"*, « [[DisposableState]], [[DisposeCapability]] »). 1. Set _newDisposableStack_.[[DisposableState]] to ~pending~. - 1. Set _newDisposableStack_.[[DisposableResourceStack]] to _disposableStack_.[[DisposableResourceStack]]. - 1. Set _disposableStack_.[[DisposableResourceStack]] to a new empty List. + 1. Set _newDisposableStack_.[[DisposeCapability]] to _disposableStack_.[[DisposeCapability]]. + 1. Set _disposableStack_.[[DisposeCapability]] to NewDisposeCapability(). 1. Set _disposableStack_.[[DisposableState]] to ~disposed~. 1. Return _newDisposableStack_. @@ -46747,13 +46793,7 @@

DisposableStack.prototype.use ( _value_ )

1. Let _disposableStack_ be the *this* value. 1. Perform ? RequireInternalSlot(_disposableStack_, [[DisposableState]]). 1. If _disposableStack_.[[DisposableState]] is ~disposed~, throw a *ReferenceError* exception. - 1. If _value_ is neither *null* nor *undefined*, then - 1. If _value_ is not an Object, throw a *TypeError* exception. - 1. Let _method_ be ? GetDisposeMethod(_value_, ~sync-dispose~). - 1. If _method_ is *undefined*, then - 1. Throw a *TypeError* exception. - 1. Else, - 1. Perform ? AddDisposableResource(_disposableStack_, _value_, ~sync-dispose~, _method_). + 1. Perform ? AddDisposableResource(_disposableStack_.[[DisposeCapability]], _value_, ~sync-dispose~). 1. Return _value_. @@ -46799,10 +46839,10 @@

Properties of DisposableStack Instances

- [[DisposableResourceStack]] + [[DisposeCapability]] - a List of DisposableResource Records + a DisposeCapability Record Resources to be disposed when the disposable stack is disposed. @@ -48262,7 +48302,7 @@

1. Else, 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. 1. Let _result_ be _generatorBody_(). - 1. Set _result_ to Completion(DisposeResources(_env_, _result_)). + 1. Set _result_ to Completion(DisposeResources(_env_.[[DisposeCapability]], _result_)). 1. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return. 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. Set _acGenerator_.[[GeneratorState]] to ~completed~. @@ -48621,7 +48661,7 @@

1. Else, 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. 1. Let _result_ be Completion(_generatorBody_()). - 1. Set _result_ to Completion(DisposeResources(_env_, _result_)). + 1. Set _result_ to Completion(DisposeResources(_env_.[[DisposeCapability]], _result_)). 1. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return. 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. Set _acGenerator_.[[AsyncGeneratorState]] to ~completed~. @@ -49007,7 +49047,7 @@

1. Let _acAsyncContext_ be the running execution context. 1. Let _env_ be _acAsyncContext_'s LexicalEnvironment. 1. Let _result_ be Completion(Evaluation of _asyncBody_). - 1. Set _result_ to Completion(DisposeResources(_env_, _result_)). + 1. Set _result_ to Completion(DisposeResources(_env_.[[DisposeCapability]], _result_)). 1. Assert: If we return here, the async function either threw an exception or performed an implicit or explicit return; all awaiting is done. 1. Remove _acAsyncContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. If _result_ is a normal completion, then From f170792e81bb6914ed55b7a8337edbc3b95622dc Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Jan 2023 16:28:11 -0500 Subject: [PATCH 21/56] Wrap UpdateEmpty calls in calls to Completion --- spec.html | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/spec.html b/spec.html index 39ec7a3369..eb0ee69271 100644 --- a/spec.html +++ b/spec.html @@ -21434,7 +21434,8 @@

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]], UpdateEmpty(_blockValue_, *undefined*))). + 1. Set _blockValue_ to Completion(UpdateEmpty(_blockValue_, *undefined*)). + 1. Set _blockValue_ to Completion(DisposeResources(_blockEnv_.[[DisposeCapability]], _blockValue_)). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return ? _blockValue_. @@ -22533,7 +22534,8 @@

1. Else, 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~normal~)). 1. If _status_ is an abrupt completion, then - 1. Set _status_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], UpdateEmpty(_status_, *undefined*))). + 1. Set _status_ to Completion(UpdateEmpty(_status_, *undefined*)). + 1. Set _status_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], _status_)). 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 @@ -22542,7 +22544,8 @@

1. Assert: _iterationKind_ is ~iterate~. 1. Return ? IteratorClose(_iteratorRecord_, _status_). 1. Let _result_ be Completion(Evaluation of _stmt_). - 1. Set _result_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], UpdateEmpty(_result_, *undefined*))). + 1. Set _result_ to Completion(UpdateEmpty(_result_, *undefined*)). + 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 @@ -23728,7 +23731,8 @@

1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). 1. Let _result_ be Completion(Evaluation of |FunctionStatementList|). 1. Let _env_ be the running execution context's LexicalEnvironment. - 1. Return ? DisposeResources(_env_.[[DisposeCapability]], UpdateEmpty(_result_, *undefined*)). + 1. Set _result_ to Completion(UpdateEmpty(_result_, *undefined*)). + 1. Return ? DisposeResources(_env_.[[DisposeCapability]], _result_). @@ -25118,7 +25122,8 @@

1. Perform ! FunctionDeclarationInstantiation(_functionObject_, « »). 1. Let _result_ be Completion(Evaluation of |ClassStaticBlockStatementList|). 1. Let _env_ be the running execution context's LexicalEnvironment. - 1. Return ? DisposeResources(_env_.[[DisposeCapability]], UpdateEmpty(_result_, *undefined*)). + 1. Set _result_ to Completion(UpdateEmpty(_result_, *undefined*)). + 1. Return ? DisposeResources(_env_.[[DisposeCapability]], _result_). From e2b268877b80fee541541054a794efd4971d550e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Jan 2023 16:28:36 -0500 Subject: [PATCH 22/56] Run formatter --- spec.html | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spec.html b/spec.html index eb0ee69271..b3695414a6 100644 --- a/spec.html +++ b/spec.html @@ -7182,7 +7182,6 @@

DisposeCapability Records

DisposeCapability Records have the fields listed in :

- -
Field Name @@ -7205,7 +7204,6 @@

DisposeCapability Records

The resources to be disposed. Resources are added in the order they are initialized, and are disposed in reverse order.
@@ -7269,8 +7267,7 @@

DisposableResource Records

- NewDisposeCapability ( - ): a DisposeCapability Record + NewDisposeCapability (): a DisposeCapability Record

From dcc071fdb951610a18486fe36ef56c6dfe0c30b0 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Jan 2023 16:30:09 -0500 Subject: [PATCH 23/56] Run formatter again --- spec.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spec.html b/spec.html index b3695414a6..d48ed6fd3e 100644 --- a/spec.html +++ b/spec.html @@ -7266,9 +7266,7 @@

DisposableResource Records

-

- NewDisposeCapability (): a DisposeCapability Record -

+

NewDisposeCapability ( ): a DisposeCapability Record

1. Let _stack_ be a new empty List. From 66a6fd9e42ec4805fcdc9a331925cdc85d6dc088 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 26 Jan 2023 11:26:12 -0500 Subject: [PATCH 24/56] Fix formatting and capitalization --- package-lock.json | 1 + spec.html | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index deb1067a82..bd2ac49ed1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "ecma262", "version": "1.0.0", "license": "SEE LICENSE IN https://tc39.es/ecma262/#sec-copyright-and-software-license", "devDependencies": { diff --git a/spec.html b/spec.html index d48ed6fd3e..487fe62598 100644 --- a/spec.html +++ b/spec.html @@ -7198,7 +7198,7 @@

DisposeCapability Records

[[DisposableResourceStack]] - A List of DisposableResource Records. + 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. @@ -7267,7 +7267,8 @@

DisposableResource Records

NewDisposeCapability ( ): a DisposeCapability Record

-
+
+
1. Let _stack_ be a new empty List. 1. Return the DisposeCapability Record { [[DisposableResourceStack]]: _stack_ }. From b0ce449b416c8f1936fe7f01e7792bc80909e9ce Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 26 Jan 2023 11:33:51 -0500 Subject: [PATCH 25/56] Clean up DisposeResources signature, replace UpdateEmpty with assertions --- esmeta-ignore.json | 2 ++ spec.html | 13 ++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/esmeta-ignore.json b/esmeta-ignore.json index 596be4c2e9..dcb6101596 100644 --- a/esmeta-ignore.json +++ b/esmeta-ignore.json @@ -15,10 +15,12 @@ "BoundFunctionCreate", "Catch[0,0].CatchClauseEvaluation", "Catch[1,0].CatchClauseEvaluation", + "ClassStaticBlockBody[0,0].EvaluateClassStaticBlockBody", "CreateBuiltinFunction", "CreateMappedArgumentsObject", "CreateSharedByteDataBlock", "ForIn/OfBodyEvaluation", + "FunctionBody[0,0].EvaluateFunctionBody", "GeneratorBody[0,0].EvaluateGeneratorBody", "GetGlobalObject", "GetMethod", diff --git a/spec.html b/spec.html index 487fe62598..9bfa841d2c 100644 --- a/spec.html +++ b/spec.html @@ -7366,8 +7366,8 @@

DisposeResources ( _disposeCapability_: a DisposeCapability Record, - _completion_: either a normal completion containing an ECMAScript language value, or an abrupt completion, - ): either a normal completion containing an ECMAScript language value, or an abrupt completion + _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

@@ -21430,7 +21430,6 @@

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(UpdateEmpty(_blockValue_, *undefined*)). 1. Set _blockValue_ to Completion(DisposeResources(_blockEnv_.[[DisposeCapability]], _blockValue_)). 1. Set the running execution context's LexicalEnvironment to _oldEnv_. 1. Return ? _blockValue_. @@ -22132,6 +22131,7 @@

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. @@ -22139,6 +22139,7 @@

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_. @@ -22530,8 +22531,8 @@

1. Else, 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~normal~)). 1. If _status_ is an abrupt completion, then - 1. Set _status_ to Completion(UpdateEmpty(_status_, *undefined*)). 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 @@ -22540,7 +22541,6 @@

1. Assert: _iterationKind_ is ~iterate~. 1. Return ? IteratorClose(_iteratorRecord_, _status_). 1. Let _result_ be Completion(Evaluation of _stmt_). - 1. Set _result_ to Completion(UpdateEmpty(_result_, *undefined*)). 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 @@ -23033,6 +23033,7 @@

Runtime Semantics: Evaluation

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_.
@@ -23727,7 +23728,6 @@

1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). 1. Let _result_ be Completion(Evaluation of |FunctionStatementList|). 1. Let _env_ be the running execution context's LexicalEnvironment. - 1. Set _result_ to Completion(UpdateEmpty(_result_, *undefined*)). 1. Return ? DisposeResources(_env_.[[DisposeCapability]], _result_). @@ -25118,7 +25118,6 @@

1. Perform ! FunctionDeclarationInstantiation(_functionObject_, « »). 1. Let _result_ be Completion(Evaluation of |ClassStaticBlockStatementList|). 1. Let _env_ be the running execution context's LexicalEnvironment. - 1. Set _result_ to Completion(UpdateEmpty(_result_, *undefined*)). 1. Return ? DisposeResources(_env_.[[DisposeCapability]], _result_). From 23bb9d14d193954a072e5ea78f5b44384284fd4a Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Jan 2023 17:11:37 -0500 Subject: [PATCH 26/56] Add 'either' in front of 'null or undefined' --- spec.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 9bfa841d2c..dee751b3df 100644 --- a/spec.html +++ b/spec.html @@ -7288,11 +7288,11 @@

1. If _method_ is not present, then - 1. If _V_ is *null* or *undefined*, return ~unused~. + 1. If _V_ is either *null* or *undefined*, return ~unused~. 1. If _V_ is not an Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_). 1. Else, - 1. If _V_ is *null* or *undefined*, then + 1. If _V_ is either *null* or *undefined*, then 1. Let _resource_ be ? CreateDisposableResource(*undefined*, _hint_, _method_). 1. Else, 1. If _V_ is not an Object, throw a *TypeError* exception. From f4859bacc709a178d0244eff9fb534f0d2c979d8 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Jan 2023 18:46:00 -0500 Subject: [PATCH 27/56] Use CreateBuiltinFunction --- spec.html | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/spec.html b/spec.html index dee751b3df..2d49c016c4 100644 --- a/spec.html +++ b/spec.html @@ -46715,23 +46715,12 @@

DisposableStack.prototype.adopt ( _value_, _onDispose_ )

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 _F_ be a new built-in function object as defined in . - 1. Set _F_.[[Argument]] to _value_. - 1. Set _F_.[[OnDisposeCallback]] to _onDispose_. + 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 Adopt Callback Functions

-

A DisposableStack adopt callback function is an anonymous built-in function object that has [[Argument]] and [[OnDisposeCallback]] internal slots.

-

When a DisposableStack adopt callback function is called, the following steps are taken:

- - 1. Let _F_ be the active function object. - 1. Assert: IsCallable(_F_.[[OnDisposeCallback]]) is *true*. - 1. Return ? Call(_F_.[[OnDisposeCallback]], *undefined*, « _F_.[[Argument]] »). - -
From 39577fdc7522ea15dea75791962b1cc36da71b25 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Jan 2023 20:32:51 -0500 Subject: [PATCH 28/56] Address additional editor feedback (from async PR) --- spec.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spec.html b/spec.html index 2d49c016c4..6c4f299669 100644 --- a/spec.html +++ b/spec.html @@ -22531,7 +22531,8 @@

1. Else, 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~normal~)). 1. If _status_ is an abrupt completion, then - 1. Set _status_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], _status_)). + 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_). @@ -22541,7 +22542,8 @@

1. Assert: _iterationKind_ is ~iterate~. 1. Return ? IteratorClose(_iteratorRecord_, _status_). 1. Let _result_ be Completion(Evaluation of _stmt_). - 1. Set _result_ to Completion(DisposeResources(_iterationEnv_.[[DisposeCapability]], _result_)). + 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 @@ -31548,8 +31550,8 @@

SuppressedError ( _error_, _suppressed_, _message_ [ , _options_ ] )

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 _msg_ be ? ToString(_message_). - 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"message"*, _msg_). + 1. Let _messageString_ be ? ToString(_message_). + 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"message"*, _messageString_). 1. Perform ? InstallErrorCause(_O_, _options_). 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"error"*, _error_). 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"suppressed"*, _suppressed_). From 639135453b8c7d141455c65b9a893a3d4f59001d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 30 Jan 2023 14:45:54 -0500 Subject: [PATCH 29/56] Move BindingPattern restriction for 'using' to an early error --- spec.html | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/spec.html b/spec.html index 6c4f299669..bcf9db391c 100644 --- a/spec.html +++ b/spec.html @@ -21502,7 +21502,7 @@

Let, Const, and Using Declarations

Syntax

LexicalDeclaration[In, Yield, Await] : - LetOrConst BindingList[?In, ?Yield, ?Await, ~Using] `;` + LetOrConst BindingList[?In, ?Yield, ?Await] `;` UsingDeclaration[?In, ?Yield, ?Await] LetOrConst : @@ -21510,15 +21510,15 @@

Syntax

`const` UsingDeclaration[In, Yield, Await] : - `using` [no LineTerminator here] [lookahead != `await`] BindingList[?In, ?Yield, ?Await, +Using] `;` + `using` [no LineTerminator here] [lookahead != `await`] BindingList[?In, ?Yield, ?Await] `;` - BindingList[In, Yield, Await, Using] : - LexicalBinding[?In, ?Yield, ?Await, ?Using] - BindingList[?In, ?Yield, ?Await, ?Using] `,` LexicalBinding[?In, ?Yield, ?Await, ?Using] + BindingList[In, Yield, Await] : + LexicalBinding[?In, ?Yield, ?Await] + BindingList[?In, ?Yield, ?Await] `,` LexicalBinding[?In, ?Yield, ?Await] - LexicalBinding[In, Yield, Await, Using] : + LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]? - [~Using] BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] + BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
@@ -21553,6 +21553,12 @@

Static Semantics: Early Errors

It is a Syntax Error if |Initializer| is not present and IsConstantDeclaration of the |LexicalDeclaration| containing this |LexicalBinding| is *true*. + LexicalBinding : BindingPattern Initializer +
    +
  • + It is a Syntax Error IsUsingDeclaration of the |LexicalDeclaration| containing this |LexicalBinding| is *true*. +
  • +
@@ -22205,22 +22211,22 @@

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, ~Using] `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, ~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, ~Using] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] + `for` `(` `var` ForBinding[?Yield, ?Await] `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, ~Using] `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` `(` [lookahead != `using` `of`] ForDeclaration[?Yield, ?Await, +Using] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await, Using] : - LetOrConst ForBinding[?Yield, ?Await, ~Using] - [+Using] `using` [no LineTerminator here] [lookahead != `await`] ForBinding[?Yield, ?Await, +Using] + LetOrConst ForBinding[?Yield, ?Await] + [+Using] `using` [no LineTerminator here] [lookahead != `await`] ForBinding[?Yield, ?Await] - ForBinding[Yield, Await, Using] : + ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] - [~Using] BindingPattern[?Yield, ?Await] + BindingPattern[?Yield, ?Await]

This section is extended by Annex .

@@ -22279,6 +22285,12 @@

Static Semantics: Early Errors

It is a Syntax Error if the BoundNames of |ForDeclaration| contains any duplicate entries. + ForBinding : BindingPattern +
    +
  • + It is a Syntax Error if this |ForBinding| is contained within a |ForDeclaration| and IsUsingDeclaration of that |ForDeclaration| is *true*. +
  • +
From dfd086cf823953398f5c9d2ad535f3c5782a5fc3 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 30 Jan 2023 15:16:39 -0500 Subject: [PATCH 30/56] Fix typo in using declaration early errors --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index bcf9db391c..79680b5353 100644 --- a/spec.html +++ b/spec.html @@ -21556,7 +21556,7 @@

Static Semantics: Early Errors

LexicalBinding : BindingPattern Initializer
  • - It is a Syntax Error IsUsingDeclaration of the |LexicalDeclaration| containing this |LexicalBinding| is *true*. + It is a Syntax Error if IsUsingDeclaration of the |LexicalDeclaration| containing this |LexicalBinding| is *true*.
From 62f1dc5af82fd5e31ac25bf949307d70be84a7fa Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 30 Jan 2023 16:16:50 -0500 Subject: [PATCH 31/56] Fix typos --- spec.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 79680b5353..a7168a4086 100644 --- a/spec.html +++ b/spec.html @@ -21607,7 +21607,7 @@

1. Else, 1. Let _rhs_ be ? Evaluation of |Initializer|. 1. Let _value_ be ? GetValue(_rhs_). - 1. Perform ! InitializeReferencedBinding(_lhs_, _value_, _hint_). + 1. Perform ? InitializeReferencedBinding(_lhs_, _value_, _hint_). 1. Return ~unused~. LexicalBinding : BindingPattern Initializer @@ -22545,7 +22545,7 @@

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. 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 From 78abb8b08ab129e9c1e01f4c76a710a8615518aa Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 30 Jan 2023 16:19:34 -0500 Subject: [PATCH 32/56] run formatter --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index a7168a4086..bc9ed29de3 100644 --- a/spec.html +++ b/spec.html @@ -46730,7 +46730,7 @@

DisposableStack.prototype.adopt ( _value_, _onDispose_ )

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. Return ? Call(_onDispose_, *undefined*, « _value_ »). 1. Let _F_ be CreateBuiltinFunction(_closure_, 0, *""*, « »). 1. Perform ? AddDisposableResource(_disposableStack_.[[DisposeCapability]], *undefined*, ~sync-dispose~, _F_). 1. Return _value_. From 583df1aa93daec09b5887cc8c2ad59665bf105fe Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 31 Jan 2023 13:57:45 -0500 Subject: [PATCH 33/56] Remove InstallErrorCause from SuppressedError, per 2023-jan consensus --- spec.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec.html b/spec.html index bc9ed29de3..ce64e58dde 100644 --- a/spec.html +++ b/spec.html @@ -31556,7 +31556,7 @@

The SuppressedError Constructor

-

SuppressedError ( _error_, _suppressed_, _message_ [ , _options_ ] )

+

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. @@ -31564,7 +31564,6 @@

SuppressedError ( _error_, _suppressed_, _message_ [ , _options_ ] )

1. If _message_ is not *undefined*, then 1. Let _messageString_ be ? ToString(_message_). 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"message"*, _messageString_). - 1. Perform ? InstallErrorCause(_O_, _options_). 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"error"*, _error_). 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"suppressed"*, _suppressed_). 1. Return _O_. From 4fed1173f341700bf894188621c037e2e4ed675a Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 27 Jan 2023 10:21:39 -0500 Subject: [PATCH 34/56] Spec text for proposal-async-explicit-resource-management --- spec.html | 463 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 420 insertions(+), 43 deletions(-) diff --git a/spec.html b/spec.html index ce64e58dde..d7a1ce04ca 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 `using await` declaration and AsyncDisposableStack objects. + + @@asyncIterator @@ -3299,6 +3310,17 @@

Well-Known Intrinsic Objects

The prototype of Array iterator objects () + + + %AsyncDisposableStack% + + + `AsyncDisposableStack` + + + The AsyncDisposableStack constructor () + + %AsyncFromSyncIteratorPrototype% @@ -4361,7 +4383,7 @@

InitializeReferencedBinding ( _V_: a Reference Record, _W_: an ECMAScript language value, - _hint_: either ~normal~ or ~sync-dispose~, + _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or an abrupt completion

@@ -7230,7 +7252,7 @@

DisposableResource Records

[[ResourceValue]] - an Object or *undefined* + an ECMAScript language value. The value to be disposed. @@ -7241,10 +7263,10 @@

DisposableResource Records

[[Hint]] - ~sync-dispose~ + ~sync-dispose~ or ~async-dispose~ - Indicates that the resource was added by a `using` declaration or DisposableStack object. + Indicates whether the resource was added by a `using` declaration or DisposableStack object (~sync-dispose~) or a `using await` declaration or AsyncDisposableStack object (~async-dispose~). @@ -7252,7 +7274,7 @@

DisposableResource Records

[[DisposeMethod]] - a function object + a function object or *undefined* A function object that will be called with [[ResourceValue]] as its *this* value when the resource disposed. @@ -7260,9 +7282,6 @@

DisposableResource Records

- - Currently, the only allowed value for [[Hint]] is ~sync-dispose~. - @@ -7280,7 +7299,7 @@

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

@@ -7288,28 +7307,23 @@

1. If _method_ is not present, then - 1. If _V_ is either *null* or *undefined*, return ~unused~. - 1. If _V_ is not an Object, throw a *TypeError* exception. + 1. If _V_ is either *null* or *undefined* and _hint_ is ~sync-dispose~, return ~unused~. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_). 1. Else, 1. If _V_ is either *null* or *undefined*, then 1. Let _resource_ be ? CreateDisposableResource(*undefined*, _hint_, _method_). 1. Else, - 1. If _V_ is not an Object, throw a *TypeError* exception. 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_, _method_). 1. Append _resource_ to _disposeCapability_.[[DisposableResourceStack]]. 1. Return ~unused~. - - Currently, the only allowed value for _hint_ is ~sync-dispose~. -

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

@@ -7317,30 +7331,36 @@

1. If _method_ is not present, then - 1. If _V_ is *undefined*, throw a *TypeError* exception. - 1. Set _method_ to ? GetDisposeMethod(_V_, _hint_). - 1. If _method_ is *undefined*, throw a *TypeError* exception. + 1. If _V_ is *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 _V_ is not an Object, throw a *TypeError* exception. 1. If IsCallable(_method_) is *false*, throw a *TypeError* exception. 1. Return the DisposableResource Record { [[ResourceValue]]: _V_, [[Hint]]: _hint_, [[DisposeMethod]]: _method_ }. - - Currently, the only allowed value for _hint_ is ~sync-dispose~. -

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

- 1. Assert: _hint_ is ~sync-dispose~. - 1. Let _method_ be ? GetMethod(_V_, @@dispose). + 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. Else, + 1. Let _method_ be ? GetMethod(_V_, @@dispose). 1. Return _method_.
@@ -7349,15 +7369,17 @@

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

- 1. Assert: _hint_ is ~sync-dispose~. - 1. Perform ? Call(_method_, _V_). + 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*. @@ -7431,7 +7453,11 @@

Static Semantics: BoundNames ( ): a List of Strings

1. Return the BoundNames of |BindingList|. - UsingDeclaration : `using` BindingList `;` + + UsingDeclaration : + `using` BindingList `;` + `using` `await` BindingList `;` + 1. Return the BoundNames of |BindingList|. @@ -7771,7 +7797,74 @@

Static Semantics: IsUsingDeclaration ( ): a Boolean

1. Return *false*. + + ForDeclaration : + `using` ForBinding + `using` `await` 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: IsUsingAwaitDeclaration ( ): a Boolean

+
+
+ LexicalDeclaration : LetOrConst BindingList `;` + + 1. Return *false*. + + UsingDeclaration : `using` BindingList `;` + + 1. Return *false*. + + UsingDeclaration : `using` `await` BindingList `;` + + 1. Return *true*. + ForDeclaration : `using` ForBinding + + 1. Return *false*. + + ForDeclaration : `using` `await` ForBinding 1. Return *true*. @@ -10296,7 +10389,7 @@

The Environment Record Type Hierarchy

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. _hint_ indicates whether the binding came from either a `using` declaration (~sync-dispose~) or a regular variable declaration (~normal~). + 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~), a `using await` declaration (~async-dispose~), or a regular variable declaration (~normal~). @@ -10353,7 +10446,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 that must be disposed when the Evaluation step that constructed the Environment Record has completed.

+

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 `using await` 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.

@@ -10422,7 +10515,7 @@

InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, - _hint_: either ~normal~ or ~sync-dispose~, + _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or a throw completion

@@ -10664,7 +10757,7 @@

InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, - _hint_: either ~normal~ or ~sync-dispose~, + _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or a throw completion

@@ -11174,7 +11267,7 @@

InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, - _hint_: either ~normal~ or ~sync-dispose~, + _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or a throw completion

@@ -21497,7 +21590,7 @@

Declarations and the Variable Statement

Let, Const, and Using Declarations

-

`let`, `const`, and `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.

+

`let`, `const`, `using`, and `using await` 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

@@ -21511,6 +21604,7 @@

Syntax

UsingDeclaration[In, Yield, Await] : `using` [no LineTerminator here] [lookahead != `await`] BindingList[?In, ?Yield, ?Await] `;` + [+Await] `using` [no LineTerminator here] `await` [no LineTerminator here] BindingList[?In, ?Yield, +Await] `;` BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] @@ -21535,6 +21629,7 @@

Static Semantics: Early Errors

UsingDeclaration : `using` BindingList `;` + `using` `await` BindingList `;`
  • @@ -21573,12 +21668,17 @@

    Runtime Semantics: Evaluation

    1. Perform ? BindingEvaluation of |BindingList| with argument ~sync-dispose~. 1. Return ~empty~. + UsingDeclaration : `using` `await` BindingList `;` + + 1. Perform ? BindingEvaluation of |BindingList| with argument ~async-dispose~. + 1. Return ~empty~. +

    Runtime Semantics: BindingEvaluation ( - _hint_: either ~normal~ or ~sync-dispose~, + _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or an abrupt completion

    @@ -22223,6 +22323,7 @@

    Syntax

    ForDeclaration[Yield, Await, Using] : LetOrConst ForBinding[?Yield, ?Await] [+Using] `using` [no LineTerminator here] [lookahead != `await`] ForBinding[?Yield, ?Await] + [+Using, +Await] `using` [no LineTerminator here] `await` [no LineTerminator here] ForBinding[?Yield, +Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] @@ -22374,7 +22475,11 @@

    1. Perform ! _environment_.CreateMutableBinding(_name_, *false*). 1. Return ~unused~. - ForDeclaration : `using` ForBinding + + ForDeclaration : + `using` ForBinding + `using` `await` ForBinding + 1. Assert: _environment_ is a Declarative Environment Record. 1. For each element _name_ of the BoundNames of |ForBinding|, do @@ -22500,6 +22605,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 IsUsingAwaitDeclaration 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|. @@ -22538,10 +22649,7 @@

    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. If IsUsingDeclaration of _lhs_ is *true*, then - 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~sync-dispose~)). - 1. Else, - 1. Let _status_ be Completion(InitializeReferencedBinding(_lhsRef_, _nextValue_, ~normal~)). + 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_)). @@ -25732,6 +25840,9 @@

    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 `using await` 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 @@ -46453,6 +46564,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:

    @@ -46666,6 +46801,41 @@

    The Disposable Interface

    + + +

    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 `using await` declaration, as the resource will be automatically disposed when the |Block| or |Module| immediately containing the declaration has been evaluated.

    +
    +
    +
    @@ -46855,6 +47025,213 @@

    Properties of DisposableStack Instances

    + +

    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%.
    • +
    +
    + + +

    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 _F_ be a new built-in function object as defined in . + 1. Set _F_.[[Argument]] to _value_. + 1. Set _F_.[[OnDisposeAsyncCallback]] to _onDisposeAsync_. + 1. Perform ? AddDisposableResource(_asyncDisposableStack_.[[DisposeCapability]], *undefined*, ~async-dispose~, _F_). + 1. Return _value_. + + + +

    AsyncDisposableStack Adopt Callback Functions

    +

    An AsyncDisposableStack adopt callback function is an anonymous built-in function that has [[Argument]] and [[OnDisposeAsyncCallback]] internal slots.

    +

    When an AsyncDisposableStack adopt callback function is called, the following steps are taken:

    + + 1. Let _F_ be the active function object. + 1. Assert: IsCallable(_F_.[[OnDisposeAsyncCallback]]) is *true*. + 1. Return ? Call(_F_.[[OnDisposeAsyncCallback]], *undefined*, « _F_.[[Argument]] »). + +
    +
    + + +

    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.

    From 0de8de85e96011a1f245d71134cd09e9140c5e7f Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 27 Jan 2023 10:29:16 -0500 Subject: [PATCH 35/56] Run formatter --- spec.html | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/spec.html b/spec.html index d7a1ce04ca..e5c285578e 100644 --- a/spec.html +++ b/spec.html @@ -46805,9 +46805,8 @@

    The Disposable Interface

    The AsyncDisposable Interface

    The AsyncDisposable interface includes the property described in :

    - + - -
    Property @@ -46832,7 +46831,6 @@

    The AsyncDisposable Interface

    When using an AsyncDisposable object, it is good practice to create the instance with a `using await` declaration, as the resource will be automatically disposed when the |Block| or |Module| immediately containing the declaration has been evaluated.

    @@ -47050,7 +47048,7 @@

    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. Let _asyncDisposableStack_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%AsyncDisposableStack.prototype%"*, « [[AsyncDisposableState]], [[DisposeCapability]] »). 1. Set _asyncDisposableStack_.[[AsyncDisposableState]] to ~pending~. 1. Set _asyncDisposableStack_.[[DisposeCapability]] to NewDisposeCapability(). 1. Return _asyncDisposableStack_. @@ -47098,7 +47096,7 @@

    AsyncDisposableStack Adopt Callback Functions

    1. Let _F_ be the active function object. 1. Assert: IsCallable(_F_.[[OnDisposeAsyncCallback]]) is *true*. - 1. Return ? Call(_F_.[[OnDisposeAsyncCallback]], *undefined*, « _F_.[[Argument]] »). + 1. Return ? Call(_F_.[[OnDisposeAsyncCallback]], *undefined*, « _F_.[[Argument]] »).
    @@ -47123,15 +47121,15 @@

    AsyncDisposableStack.prototype.disposeAsync ( )

    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. 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. 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. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _result_ »). 1. Return _promiseCapability_.[[Promise]].
    @@ -47154,7 +47152,7 @@

    AsyncDisposableStack.prototype.move ( )

    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. 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(). @@ -47192,7 +47190,6 @@

    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 @@ -47226,7 +47223,6 @@

    Properties of AsyncDisposableStack Instances

    Resources to be disposed when the disposable stack is disposed.
    From de2bc5647c20dd615ac1653c3836685dc5df45cb Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Jan 2023 17:13:24 -0500 Subject: [PATCH 36/56] Add 'either' in front of 'null or undefined' --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index e5c285578e..134ba7fef2 100644 --- a/spec.html +++ b/spec.html @@ -7331,7 +7331,7 @@

    1. If _method_ is not present, then - 1. If _V_ is *null* or *undefined*, then + 1. If _V_ is either *null* or *undefined*, then 1. Set _V_ to *undefined*. 1. Set _method_ to *undefined*. 1. Else, From 08cd6b447bf9658da91a506765f8f0e2fcc58ca7 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Jan 2023 18:44:56 -0500 Subject: [PATCH 37/56] Address editor feedback --- spec.html | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/spec.html b/spec.html index 134ba7fef2..7c2015ab67 100644 --- a/spec.html +++ b/spec.html @@ -4383,7 +4383,7 @@

    InitializeReferencedBinding ( _V_: a Reference Record, _W_: an ECMAScript language value, - _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, + _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or an abrupt completion

    @@ -7789,7 +7789,11 @@

    Static Semantics: IsUsingDeclaration ( ): a Boolean

    1. Return *false*. - LexicalDeclaration : UsingDeclaration + + UsingDeclaration : + `using` BindingList `;` + `using` `await` BindingList `;` + 1. Return *true*. @@ -7860,6 +7864,10 @@

    Static Semantics: IsUsingAwaitDeclaration ( ): a Boolean

    1. Return *true*. + ForDeclaration : LetOrConst ForBinding + + 1. Return *false*. + ForDeclaration : `using` ForBinding 1. Return *false*. @@ -10515,7 +10523,7 @@

    InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, - _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, + _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or a throw completion

    @@ -10757,7 +10765,7 @@

    InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, - _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, + _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or a throw completion

    @@ -11267,7 +11275,7 @@

    InitializeBinding ( _N_: a String, _V_: an ECMAScript language value, - _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, + _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or a throw completion

    @@ -21678,7 +21686,7 @@

    Runtime Semantics: Evaluation

    Runtime Semantics: BindingEvaluation ( - _hint_: either ~normal~, ~sync-dispose~, or ~async-dispose~, + _hint_: one of ~normal~, ~sync-dispose~, or ~async-dispose~, ): either a normal completion containing ~unused~ or an abrupt completion

    @@ -47082,23 +47090,12 @@

    AsyncDisposableStack.prototype.adopt ( _value_, _onDisposeAsync_ )

    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 _F_ be a new built-in function object as defined in . - 1. Set _F_.[[Argument]] to _value_. - 1. Set _F_.[[OnDisposeAsyncCallback]] to _onDisposeAsync_. + 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 Adopt Callback Functions

    -

    An AsyncDisposableStack adopt callback function is an anonymous built-in function that has [[Argument]] and [[OnDisposeAsyncCallback]] internal slots.

    -

    When an AsyncDisposableStack adopt callback function is called, the following steps are taken:

    - - 1. Let _F_ be the active function object. - 1. Assert: IsCallable(_F_.[[OnDisposeAsyncCallback]]) is *true*. - 1. Return ? Call(_F_.[[OnDisposeAsyncCallback]], *undefined*, « _F_.[[Argument]] »). - -
    From 6be4e942806e5b4e247bd678d1118b0970ce542a Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Jan 2023 20:30:54 -0500 Subject: [PATCH 38/56] Address additional editor feedback --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 7c2015ab67..0c3f0391a4 100644 --- a/spec.html +++ b/spec.html @@ -47091,7 +47091,7 @@

    AsyncDisposableStack.prototype.adopt ( _value_, _onDisposeAsync_ )

    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. Return ? Call(_onDisposeAsync_, *undefined*, « _value_ »). 1. Let _F_ be CreateBuiltinFunction(_closure_, 0, *""*, « »). 1. Perform ? AddDisposableResource(_asyncDisposableStack_.[[DisposeCapability]], *undefined*, ~async-dispose~, _F_). 1. Return _value_. From 77ff8dbf7dfa626fbb130beabddb344aec589be1 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 22 Mar 2023 13:39:45 -0400 Subject: [PATCH 39/56] Switch back to a production parameter, update ASI note --- spec.html | 53 +++++++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/spec.html b/spec.html index 0c3f0391a4..a5c47b706e 100644 --- a/spec.html +++ b/spec.html @@ -18149,6 +18149,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] [lookahead != `await`] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` + ContinueStatement[Yield, Await] : `continue` `;` `continue` [no LineTerminator here] LabelIdentifier[?Yield, ?Await] `;` @@ -18204,6 +18207,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.
  • @@ -18222,6 +18228,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.
  • @@ -21603,7 +21612,7 @@

    Let, Const, and Using Declarations

    Syntax

    LexicalDeclaration[In, Yield, Await] : - LetOrConst BindingList[?In, ?Yield, ?Await] `;` + LetOrConst BindingList[?In, ?Yield, ?Await, +Pattern] `;` UsingDeclaration[?In, ?Yield, ?Await] LetOrConst : @@ -21611,16 +21620,16 @@

    Syntax

    `const` UsingDeclaration[In, Yield, Await] : - `using` [no LineTerminator here] [lookahead != `await`] BindingList[?In, ?Yield, ?Await] `;` - [+Await] `using` [no LineTerminator here] `await` [no LineTerminator here] BindingList[?In, ?Yield, +Await] `;` + `using` [no LineTerminator here] [lookahead != `await`] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` + [+Await] `using` [no LineTerminator here] `await` [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] `;` - BindingList[In, Yield, Await] : - LexicalBinding[?In, ?Yield, ?Await] - BindingList[?In, ?Yield, ?Await] `,` 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] : + 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]
    @@ -21656,12 +21665,6 @@

    Static Semantics: Early Errors

    It is a Syntax Error if |Initializer| is not present and IsConstantDeclaration of the |LexicalDeclaration| containing this |LexicalBinding| is *true*.
- LexicalBinding : BindingPattern Initializer -
    -
  • - It is a Syntax Error if IsUsingDeclaration of the |LexicalDeclaration| containing this |LexicalBinding| is *true*. -
  • -
@@ -22319,23 +22322,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` `(` `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` `(` `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` `(` `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, Using] : - LetOrConst ForBinding[?Yield, ?Await] - [+Using] `using` [no LineTerminator here] [lookahead != `await`] ForBinding[?Yield, ?Await] - [+Using, +Await] `using` [no LineTerminator here] `await` [no LineTerminator here] ForBinding[?Yield, +Await] + LetOrConst ForBinding[?Yield, ?Await, +Pattern] + [+Using] `using` [no LineTerminator here] [lookahead != `await`] ForBinding[?Yield, ?Await, ~Pattern] + [+Using, +Await] `using` [no LineTerminator here] `await` [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 .

@@ -22394,12 +22397,6 @@

Static Semantics: Early Errors

It is a Syntax Error if the BoundNames of |ForDeclaration| contains any duplicate entries. - ForBinding : BindingPattern -
    -
  • - It is a Syntax Error if this |ForBinding| is contained within a |ForDeclaration| and IsUsingDeclaration of that |ForDeclaration| is *true*. -
  • -
From 0e5e51aaf5fe637d277e115ec3dc35711b637391 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 27 Mar 2023 12:18:52 -0400 Subject: [PATCH 40/56] Remove 'await' restriction per March 2023 consensus. See tc39/proposal-explicit-resource-management#153 --- spec.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec.html b/spec.html index a5c47b706e..ef9ab02f2b 100644 --- a/spec.html +++ b/spec.html @@ -18150,7 +18150,7 @@

Rules of Automatic Semicolon Insertion

LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] `--` UsingDeclaration[In, Yield, Await] : - `using` [no LineTerminator here] [lookahead != `await`] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` + `using` [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` ContinueStatement[Yield, Await] : `continue` `;` @@ -21620,7 +21620,7 @@

Syntax

`const` UsingDeclaration[In, Yield, Await] : - `using` [no LineTerminator here] [lookahead != `await`] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` + `using` [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` [+Await] `using` [no LineTerminator here] `await` [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] `;` BindingList[In, Yield, Await, Pattern] : @@ -21650,7 +21650,7 @@

Static Semantics: Early Errors

  • - It is a Syntax Error if the BoundNames of |BindingList| contains *"let"* or *"await"*. + 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. @@ -22333,7 +22333,7 @@

    Syntax

    ForDeclaration[Yield, Await, Using] : LetOrConst ForBinding[?Yield, ?Await, +Pattern] - [+Using] `using` [no LineTerminator here] [lookahead != `await`] ForBinding[?Yield, ?Await, ~Pattern] + [+Using] `using` [no LineTerminator here] ForBinding[?Yield, ?Await, ~Pattern] [+Using, +Await] `using` [no LineTerminator here] `await` [no LineTerminator here] ForBinding[?Yield, +Await, ~Pattern] ForBinding[Yield, Await, Pattern] : From ca51702f5d296a9a3bead9e26ffd835cf2da6d53 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 20 Mar 2024 15:33:56 -0400 Subject: [PATCH 41/56] Adopt consensus changes from tc39/proposal-explicit-resource-management#178 --- spec.html | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/spec.html b/spec.html index ef9ab02f2b..004bdbe385 100644 --- a/spec.html +++ b/spec.html @@ -23852,10 +23852,8 @@

FunctionBody : FunctionStatementList - 1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). - 1. Let _result_ be Completion(Evaluation of |FunctionStatementList|). - 1. Let _env_ be the running execution context's LexicalEnvironment. - 1. Return ? DisposeResources(_env_.[[DisposeCapability]], _result_). + 1. Perform ! FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). + 1. Return ? Evaluation of |FunctionStatementList|). @@ -23955,6 +23953,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_). + @@ -48664,14 +48669,12 @@

1. Set the Generator component of _genContext_ to _generator_. 1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ and performs the following steps when called: 1. Let _acGenContext_ be the running execution context. - 1. Let _env_ be _acGenContext_'s LexicalEnvironment. 1. Let _acGenerator_ be the Generator component of _acGenContext_. 1. If _generatorBody_ is a Parse Node, then 1. Let _result_ be Completion(Evaluation of _generatorBody_). 1. Else, 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. 1. Let _result_ be _generatorBody_(). - 1. Set _result_ to Completion(DisposeResources(_env_.[[DisposeCapability]], _result_)). 1. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return. 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. Set _acGenerator_.[[GeneratorState]] to ~completed~. @@ -49023,14 +49026,12 @@

1. Set the Generator component of _genContext_ to _generator_. 1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ and performs the following steps when called: 1. Let _acGenContext_ be the running execution context. - 1. Let _env_ be _acGenContext_'s LexicalEnvironment. 1. Let _acGenerator_ be the Generator component of _acGenContext_. 1. If _generatorBody_ is a Parse Node, then 1. Let _result_ be Completion(Evaluation of _generatorBody_). 1. Else, 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. 1. Let _result_ be Completion(_generatorBody_()). - 1. Set _result_ to Completion(DisposeResources(_env_.[[DisposeCapability]], _result_)). 1. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return. 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. Set _acGenerator_.[[AsyncGeneratorState]] to ~completed~. @@ -49414,9 +49415,7 @@

1. Let _runningContext_ be the running execution context. 1. Let _closure_ be a new Abstract Closure with no parameters that captures _promiseCapability_ and _asyncBody_ and performs the following steps when called: 1. Let _acAsyncContext_ be the running execution context. - 1. Let _env_ be _acAsyncContext_'s LexicalEnvironment. 1. Let _result_ be Completion(Evaluation of _asyncBody_). - 1. Set _result_ to Completion(DisposeResources(_env_.[[DisposeCapability]], _result_)). 1. Assert: If we return here, the async function either threw an exception or performed an implicit or explicit return; all awaiting is done. 1. Remove _acAsyncContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. 1. If _result_ is a normal completion, then From cd30168034bff42fb15659e95009b7f2b8ec517c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 21 Mar 2024 18:23:58 -0400 Subject: [PATCH 42/56] Adopt consensus changes from tc39/proposal-explicit-resource-management#180 --- spec.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec.html b/spec.html index 004bdbe385..6d8abe40ad 100644 --- a/spec.html +++ b/spec.html @@ -7359,6 +7359,12 @@

1. Let _method_ be ? GetMethod(_V_, @@asyncDispose). 1. If _method_ is *undefined*, then 1. Set _method_ to ? GetMethod(_V_, @@dispose). + 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. Perform ? Call(_method_, _O_). + 1. Return *undefined*. + 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. + 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). 1. Else, 1. Let _method_ be ? GetMethod(_V_, @@dispose). 1. Return _method_. From e31c80e815ca8a0c7809bcf88fd6fdcec5ab46a7 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 21 Mar 2024 18:25:26 -0400 Subject: [PATCH 43/56] Adopt typo fix from tc39/proposal-explicit-resource-management#217 --- spec.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec.html b/spec.html index 6d8abe40ad..76ad718618 100644 --- a/spec.html +++ b/spec.html @@ -7359,12 +7359,12 @@

1. Let _method_ be ? GetMethod(_V_, @@asyncDispose). 1. If _method_ is *undefined*, then 1. Set _method_ to ? GetMethod(_V_, @@dispose). - 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. Perform ? Call(_method_, _O_). - 1. Return *undefined*. - 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. - 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). + 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. Perform ? Call(_method_, _O_). + 1. Return *undefined*. + 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. + 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). 1. Else, 1. Let _method_ be ? GetMethod(_V_, @@dispose). 1. Return _method_. From 2a990d97ef948bcbafabb83da48f42371d4431ea Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 22 Mar 2024 13:35:18 -0400 Subject: [PATCH 44/56] Fix typos and add temporary PR note --- spec.html | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/spec.html b/spec.html index 76ad718618..f381af3b35 100644 --- a/spec.html +++ b/spec.html @@ -7359,12 +7359,18 @@

1. Let _method_ be ? GetMethod(_V_, @@asyncDispose). 1. If _method_ is *undefined*, then 1. Set _method_ to ? GetMethod(_V_, @@dispose). - 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. Perform ? Call(_method_, _O_). - 1. Return *undefined*. - 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. - 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). + + + 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. Perform ? Call(_method_, _O_). + 1. Return *undefined*. + 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. + 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). + 1. Else, 1. Let _method_ be ? GetMethod(_V_, @@dispose). 1. Return _method_. @@ -23859,7 +23865,7 @@

FunctionBody : FunctionStatementList 1. Perform ! FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). - 1. Return ? Evaluation of |FunctionStatementList|). + 1. Return ? Evaluation of |FunctionStatementList|. From 6e90e41a160a20fb98d0d487a6f5afdbb2c81f7d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 22 Mar 2024 13:41:13 -0400 Subject: [PATCH 45/56] Remove temporary PR note --- spec.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spec.html b/spec.html index f381af3b35..9a13fedd49 100644 --- a/spec.html +++ b/spec.html @@ -7359,18 +7359,12 @@

1. Let _method_ be ? GetMethod(_V_, @@asyncDispose). 1. If _method_ is *undefined*, then 1. Set _method_ to ? GetMethod(_V_, @@dispose). - - 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. Perform ? Call(_method_, _O_). 1. Return *undefined*. 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. 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). - 1. Else, 1. Let _method_ be ? GetMethod(_V_, @@dispose). 1. Return _method_. From 59eaa3bc96e9fc4c58f5140f82064e31c6a42349 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 22 Mar 2024 16:10:41 -0400 Subject: [PATCH 46/56] Remaining consensus updates from proposal repo --- spec.html | 205 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 154 insertions(+), 51 deletions(-) diff --git a/spec.html b/spec.html index 9a13fedd49..99d332c419 100644 --- a/spec.html +++ b/spec.html @@ -1229,7 +1229,7 @@

Well-Known Symbols

`"Symbol.asyncDispose"` - A method that performs explicit resource cleanup on an object. Called by the semantics of the `using await` declaration and AsyncDisposableStack objects. + A method that performs explicit resource cleanup on an object. Called by the semantics of the `await using` declaration and AsyncDisposableStack objects. @@ -7252,7 +7252,7 @@

DisposableResource Records

[[ResourceValue]] - an ECMAScript language value. + an Object or *undefined*. The value to be disposed. @@ -7266,7 +7266,7 @@

DisposableResource Records

~sync-dispose~ or ~async-dispose~ - Indicates whether the resource was added by a `using` declaration or DisposableStack object (~sync-dispose~) or a `using await` declaration or AsyncDisposableStack object (~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~). @@ -7300,7 +7300,7 @@

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

@@ -7308,12 +7308,11 @@

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. If _V_ is either *null* or *undefined*, then - 1. Let _resource_ be ? CreateDisposableResource(*undefined*, _hint_, _method_). - 1. Else, - 1. Let _resource_ be ? CreateDisposableResource(_V_, _hint_, _method_). + 1. Assert: V is *undefined*. + 1. Let _resource_ be ? CreateDisposableResource(*undefined*, _hint_, _method_). 1. Append _resource_ to _disposeCapability_.[[DisposableResourceStack]]. 1. Return ~unused~. @@ -7324,7 +7323,7 @@

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

@@ -7339,7 +7338,6 @@

1. Set _method_ to ? GetDisposeMethod(_V_, _hint_). 1. If _method_ is *undefined*, throw a *TypeError* exception. 1. Else, - 1. If _V_ is not an Object, throw a *TypeError* exception. 1. If IsCallable(_method_) is *false*, throw a *TypeError* exception. 1. Return the DisposableResource Record { [[ResourceValue]]: _V_, [[Hint]]: _hint_, [[DisposeMethod]]: _method_ }. @@ -7400,10 +7398,10 @@

- 1. For each element _resource_ of _disposeCapability_.[[DisposableResourceStack]], in reverse List order, do + 1. For each element _resource_ of _disposeCapability_.[[DisposableResourceStack]], in reverse list order, do 1. Let _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). - 1. If _result_.[[Type]] is ~throw~, then - 1. If _completion_.[[Type]] is ~throw~, then + 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. @@ -7462,7 +7460,9 @@

Static Semantics: BoundNames ( ): a List of Strings

UsingDeclaration : `using` BindingList `;` - `using` `await` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` 1. Return the BoundNames of |BindingList|. @@ -7733,10 +7733,6 @@

Static Semantics: IsConstantDeclaration ( ): a Boolean

1. Return IsConstantDeclaration of |LetOrConst|. - LexicalDeclaration : UsingDeclaration - - 1. Return *true*. - LetOrConst : `let` 1. Return *false*. @@ -7745,6 +7741,16 @@

Static Semantics: IsConstantDeclaration ( ): a Boolean

1. Return *true*. + + UsingDeclaration : + `using` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` + + + 1. Return *true*. + FunctionDeclaration : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}` @@ -7798,7 +7804,9 @@

Static Semantics: IsUsingDeclaration ( ): a Boolean

UsingDeclaration : `using` BindingList `;` - `using` `await` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` 1. Return *true*. @@ -7810,7 +7818,7 @@

Static Semantics: IsUsingDeclaration ( ): a Boolean

ForDeclaration : `using` ForBinding - `using` `await` ForBinding + `await` `using` ForBinding 1. Return *true*. @@ -7854,8 +7862,8 @@

Static Semantics: IsUsingDeclaration ( ): a Boolean

- -

Static Semantics: IsUsingAwaitDeclaration ( ): a Boolean

+ +

Static Semantics: IsAwaitUsingDeclaration ( ): a Boolean

LexicalDeclaration : LetOrConst BindingList `;` @@ -7866,7 +7874,7 @@

Static Semantics: IsUsingAwaitDeclaration ( ): a Boolean

1. Return *false*. - UsingDeclaration : `using` `await` BindingList `;` + AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` 1. Return *true*. @@ -7878,7 +7886,7 @@

Static Semantics: IsUsingAwaitDeclaration ( ): a Boolean

1. Return *false*. - ForDeclaration : `using` `await` ForBinding + ForDeclaration : `await` `using` ForBinding 1. Return *true*. @@ -9394,7 +9402,10 @@

Static Semantics: IsFunctionDefinition ( ): a Boolean

`-` UnaryExpression `~` UnaryExpression `!` UnaryExpression - AwaitExpression + CoverAwaitExpressionAndAwaitUsingDeclarationHead + + AwaitExpression : + `await` UnaryExpression ExponentiationExpression : UpdateExpression `**` ExponentiationExpression @@ -10175,7 +10186,10 @@

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

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

The Environment Record Type Hierarchy

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. _hint_ indicates whether the binding came from either a `using` declaration (~sync-dispose~), a `using await` declaration (~async-dispose~), or a regular variable declaration (~normal~). + 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~). @@ -10460,7 +10474,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 `using await` declarations that must be disposed when the Evaluation step that constructed the Environment Record has completed.

+

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.

@@ -11801,6 +11815,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_. @@ -11838,6 +11853,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_. @@ -17030,7 +17046,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 `_`;

    @@ -20203,7 +20219,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] @@ -21610,16 +21640,17 @@

    Declarations and the Variable Statement

    - -

    Let, Const, and Using Declarations

    + +

    Let, Const, Using, and Await Using Declarations

    -

    `let`, `const`, `using`, and `using await` 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, +Pattern] `;` UsingDeclaration[?In, ?Yield, ?Await] + [+Await] AwaitUsingDeclaration[?In, ?Yield] LetOrConst : `let` @@ -21627,7 +21658,9 @@

    Syntax

    UsingDeclaration[In, Yield, Await] : `using` [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] `;` - [+Await] `using` [no LineTerminator here] `await` [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] `;` + + AwaitUsingDeclaration[In, Yield] : + CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] `;` BindingList[In, Yield, Await, Pattern] : LexicalBinding[?In, ?Yield, ?Await, ?Pattern] @@ -21638,7 +21671,18 @@

    Syntax

    [+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 `;`
      @@ -21652,7 +21696,6 @@

      Static Semantics: Early Errors

      UsingDeclaration : `using` BindingList `;` - `using` `await` BindingList `;`
      • @@ -21665,6 +21708,22 @@

        Static Semantics: Early Errors

        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|, |ClassStaticBlockBody|, or |ClassBody|.
      + + 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|, |ClassStaticBlockBody|, or |ClassBody|. +
      • +
      LexicalBinding : BindingIdentifier Initializer?
      • @@ -21673,7 +21732,7 @@

        Static Semantics: Early Errors

      - +

      Runtime Semantics: Evaluation

      LexicalDeclaration : LetOrConst BindingList `;` @@ -21685,14 +21744,14 @@

      Runtime Semantics: Evaluation

      1. Perform ? BindingEvaluation of |BindingList| with argument ~sync-dispose~. 1. Return ~empty~.
      - UsingDeclaration : `using` `await` BindingList `;` + 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~, @@ -21713,7 +21772,7 @@

      1. Return ~unused~. -

      A static semantics rule ensures that this form of |LexicalBinding| never occurs in a `const` or `using` declaration.

      +

      A static semantics rule ensures that this form of |LexicalBinding| never occurs in a `const`, `using`, or `await using` declaration.

      LexicalBinding : BindingIdentifier Initializer @@ -22340,7 +22399,7 @@

      Syntax

      ForDeclaration[Yield, Await, Using] : LetOrConst ForBinding[?Yield, ?Await, +Pattern] [+Using] `using` [no LineTerminator here] ForBinding[?Yield, ?Await, ~Pattern] - [+Using, +Await] `using` [no LineTerminator here] `await` [no LineTerminator here] ForBinding[?Yield, +Await, ~Pattern] + [+Using, +Await] `await` [no LineTerminator here] `using` [no LineTerminator here] ForBinding[?Yield, +Await, ~Pattern] ForBinding[Yield, Await, Pattern] : BindingIdentifier[?Yield, ?Await] @@ -22489,10 +22548,9 @@

      ForDeclaration : `using` ForBinding - `using` `await` ForBinding + `await` `using` ForBinding - 1. Assert: _environment_ is a Declarative Environment Record. 1. For each element _name_ of the BoundNames of |ForBinding|, do 1. Perform ! _environment_.CreateImmutableBinding(_name_, *true*). @@ -22616,7 +22674,7 @@

      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 IsUsingAwaitDeclaration of _lhs_ is *true*, then + 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~. @@ -23858,7 +23916,7 @@

FunctionBody : FunctionStatementList - 1. Perform ! FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). + 1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). 1. Return ? Evaluation of |FunctionStatementList|. @@ -25668,6 +25726,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 @@ -25857,7 +25922,7 @@

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 `using await` 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.

+

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 @@ -26060,7 +26125,10 @@

`-` UnaryExpression `~` UnaryExpression `!` UnaryExpression - AwaitExpression + CoverAwaitExpressionAndAwaitUsingDeclarationHead + + AwaitExpression : + `await` UnaryExpression CallExpression : SuperCall @@ -26214,7 +26282,13 @@

Static Semantics: HasUnterminatedUsingDeclaration ( ): a Boolean

1. Return *false*. - LexicalDeclaration : UsingDeclaration + + UsingDeclaration : + `using` BindingList `;` + + AwaitUsingDeclaration : + CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList `;` + 1. Return *true*. @@ -46844,7 +46918,7 @@

The AsyncDisposable Interface

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 `using await` declaration, as the resource will be automatically disposed when the |Block| or |Module| immediately containing the declaration has been evaluated.

+

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.

@@ -46891,7 +46965,14 @@

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* }.

+
@@ -46986,7 +47067,7 @@

DisposableStack.prototype.use ( _value_ )

DisposableStack.prototype [ @@dispose ] ( )

-

The initial value of the @@dispose property is %DisposableStack.prototype.dispose%, defined in .

+

The initial value of the `@@dispose` property is %DisposableStack.prototype.dispose%, defined in .

@@ -47077,7 +47158,14 @@

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* }.

+
@@ -47180,7 +47268,7 @@

AsyncDisposableStack.prototype.use ( _value_ )

AsyncDisposableStack.prototype [ @@asyncDispose ] ( )

-

The initial value of the @@asyncDispose property is %AsyncDisposableStack.prototype.disposeAsync%, defined in .

+

The initial value of the `@@asyncDispose` property is %AsyncDisposableStack.prototype.disposeAsync%, defined in .

@@ -50567,6 +50655,14 @@

Statements

+ +

+ In certain circumstances when processing an instance of the production
+
+ the interpretation of |CoverAwaitExpressionAndAwaitUsingDeclarationHead| is refined using the following grammar: +

+ +

 

@@ -50660,7 +50756,14 @@

Functions and Classes

+ +

+ When processing an instance of the production
+
+ the interpretation of |CoverAwaitExpressionAndAwaitUsingDeclarationHead| is refined using the following grammar: +

+

 

From e0d18bd6208d63cfcfd3b928d4c54dbc1b8dddec Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 22 Mar 2024 16:27:01 -0400 Subject: [PATCH 47/56] Add missing undefined check in GetDisposeMethod --- spec.html | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spec.html b/spec.html index 99d332c419..983dd8956c 100644 --- a/spec.html +++ b/spec.html @@ -7357,12 +7357,13 @@

1. Let _method_ be ? GetMethod(_V_, @@asyncDispose). 1. If _method_ is *undefined*, then 1. Set _method_ to ? GetMethod(_V_, @@dispose). - 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. Perform ? Call(_method_, _O_). - 1. Return *undefined*. - 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. - 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). + 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. Perform ? Call(_method_, _O_). + 1. Return *undefined*. + 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. + 1. Return CreateBuiltinFunction(_closure_, 0, *""*, « »). 1. Else, 1. Let _method_ be ? GetMethod(_V_, @@dispose). 1. Return _method_. From 633fa2c64d588e1efd85e6b4fd8d2de23e6acb6c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 25 Mar 2024 14:43:32 -0400 Subject: [PATCH 48/56] Fix DisposeCapability leak --- spec.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 983dd8956c..3d2073ca8e 100644 --- a/spec.html +++ b/spec.html @@ -7220,7 +7220,7 @@

DisposeCapability Records

[[DisposableResourceStack]] - a List of DisposableResource Records + either *undefined* or 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. @@ -7306,6 +7306,7 @@

+ 1. Assert: _disposeCapability_.[[DisposableResourceStack]] is not *undefined*. 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. @@ -7399,6 +7400,7 @@

+ 1. Assert: _disposeCapability_.[[DisposableResourceStack]] is not *undefined*. 1. For each element _resource_ of _disposeCapability_.[[DisposableResourceStack]], in reverse list order, do 1. Let _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). 1. If _result_ is a throw completion, then @@ -7411,6 +7413,8 @@

1. Set _completion_ to ThrowCompletion(_error_). 1. Else, 1. Set _completion_ to _result_. + 1. NOTE: After _disposeCapability_ has been disposed, it will never be used again. The contents of _disposeCapability_.[[DisposableResourceStack]] can be discarded at this point. + 1. Set _disposeCapability_.[[DisposableResourceStack]] to *undefined*. 1. Return ? _completion_. From 6cf5b01a7d2031a692d6c925b123f50121cecd99 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 25 Mar 2024 15:42:34 -0400 Subject: [PATCH 49/56] fix formatting --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 3d2073ca8e..83a2124512 100644 --- a/spec.html +++ b/spec.html @@ -7220,7 +7220,7 @@

DisposeCapability Records

[[DisposableResourceStack]] - either *undefined* or a List of DisposableResource Records + either *undefined* or 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. From 3cc21aaee085a1da02ae98aa87408b38a4591eb5 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 10 Apr 2024 13:55:36 -0400 Subject: [PATCH 50/56] Switch to empty list --- spec.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/spec.html b/spec.html index 83a2124512..86541cac1e 100644 --- a/spec.html +++ b/spec.html @@ -7220,7 +7220,7 @@

DisposeCapability Records

[[DisposableResourceStack]] - either *undefined* or a List of DisposableResource Records + 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. @@ -7306,7 +7306,6 @@

- 1. Assert: _disposeCapability_.[[DisposableResourceStack]] is not *undefined*. 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. @@ -7400,7 +7399,6 @@

- 1. Assert: _disposeCapability_.[[DisposableResourceStack]] is not *undefined*. 1. For each element _resource_ of _disposeCapability_.[[DisposableResourceStack]], in reverse list order, do 1. Let _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). 1. If _result_ is a throw completion, then @@ -7414,7 +7412,7 @@

1. Else, 1. Set _completion_ to _result_. 1. NOTE: After _disposeCapability_ has been disposed, it will never be used again. The contents of _disposeCapability_.[[DisposableResourceStack]] can be discarded at this point. - 1. Set _disposeCapability_.[[DisposableResourceStack]] to *undefined*. + 1. Set _disposeCapability_.[[DisposableResourceStack]] to a new empty List. 1. Return ? _completion_. From 5716b8100308afa123f98cc8638bc58ff2aedb98 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 10 Apr 2024 13:57:50 -0400 Subject: [PATCH 51/56] Update text of NOTE --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 86541cac1e..e3cbccd930 100644 --- a/spec.html +++ b/spec.html @@ -7411,7 +7411,7 @@

1. Set _completion_ to ThrowCompletion(_error_). 1. Else, 1. Set _completion_ to _result_. - 1. NOTE: After _disposeCapability_ has been disposed, it will never be used again. The contents of _disposeCapability_.[[DisposableResourceStack]] can be discarded at this point. + 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_. From 1cef2c836ff56c8615f66302ea790c1ca34271b2 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 10 Apr 2024 14:04:59 -0400 Subject: [PATCH 52/56] Add PromiseCapability wrapper around sync dispose in an `await using` --- spec.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spec.html b/spec.html index e3cbccd930..89936ad78e 100644 --- a/spec.html +++ b/spec.html @@ -7360,9 +7360,12 @@

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. Perform ? Call(_method_, _O_). - 1. Return *undefined*. - 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. + 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). From eafa377844267ffc5a72c15edae3f1194a1171a4 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 22 Mar 2024 16:24:59 -0400 Subject: [PATCH 53/56] Fix missing lookahead restriction --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 89936ad78e..4b436cfc3a 100644 --- a/spec.html +++ b/spec.html @@ -28969,7 +28969,7 @@

Syntax

`export` ExportFromClause FromClause `;` `export` NamedExports `;` `export` VariableStatement[~Yield, +Await] - `export` [lookahead != `using`] 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] `;` From 4914a91de337ef3bdc3c0ce04099e2ae1c4e6906 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 22 Mar 2024 16:33:12 -0400 Subject: [PATCH 54/56] Remove superfluous ClassBody restriction --- spec.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 4b436cfc3a..d11bb05ab1 100644 --- a/spec.html +++ b/spec.html @@ -21711,7 +21711,7 @@

Static Semantics: Early Errors

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|, |ClassStaticBlockBody|, or |ClassBody|. + 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|.
  • @@ -21727,7 +21727,7 @@

    Static Semantics: Early Errors

    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|, |ClassStaticBlockBody|, or |ClassBody|. + 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? From b3d400d94f26b3bb7a05c47f353ed0f23179b0c6 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 23 May 2024 20:44:54 -0400 Subject: [PATCH 55/56] Add entries to esmeta-ignore --- esmeta-ignore.json | 4 ++++ 1 file changed, 4 insertions(+) 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", From 06ac134baf878e5661b115c0e7136201d4ec4f10 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 15 Jun 2024 15:00:50 -0400 Subject: [PATCH 56/56] Reduce unnecessary Awaits for nullish values in blocks containing `await using` --- spec.html | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/spec.html b/spec.html index d11bb05ab1..48e64000bb 100644 --- a/spec.html +++ b/spec.html @@ -7402,18 +7402,36 @@

    + 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 _result_ be Completion(Dispose(_resource_.[[ResourceValue]], _resource_.[[Hint]], _resource_.[[DisposeMethod]])). - 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. 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_.