diff --git a/spec.html b/spec.html index 6c6932c0d1..210fdb94f4 100644 --- a/spec.html +++ b/spec.html @@ -2303,6 +2303,7 @@

Object Internal Methods and Internal Slots

The actual semantics of objects, in ECMAScript, are specified via algorithms called internal methods. Each object in an ECMAScript engine is associated with a set of internal methods that defines its runtime behaviour. These internal methods are not part of the ECMAScript language. They are defined by this specification purely for expository purposes. However, each object within an implementation of ECMAScript must behave as specified by the internal methods associated with it. The exact manner in which this is accomplished is determined by the implementation.

Internal method names are polymorphic. This means that different object values may perform different algorithms when a common internal method name is invoked upon them. That actual object upon which an internal method is invoked is the “target” of the invocation. If, at runtime, the implementation of an algorithm attempts to use an internal method of an object that the object does not support, a *TypeError* exception is thrown.

Internal slots correspond to internal state that is associated with objects and used by various ECMAScript specification algorithms. Internal slots are not object properties and they are not inherited. Depending upon the specific internal slot specification, such state may consist of values of any ECMAScript language type or of specific ECMAScript specification type values. Unless explicitly specified otherwise, internal slots are allocated as part of the process of creating an object and may not be dynamically added to an object. Unless specified otherwise, the initial value of an internal slot is the value *undefined*. Various algorithms within this specification create objects that have internal slots. However, the ECMAScript language provides no direct way to associate internal slots with an object.

+

All objects have an internal slot named [[PrivateElements]], which is a List of PrivateElements. This List represents the values of the private fields, methods, and accessors for the object. Initially, it is an empty List.

Internal methods and internal slots are identified within this specification using names enclosed in double square brackets [[ ]].

summarizes the essential internal methods used by this specification that are applicable to all objects created or manipulated by ECMAScript code. Every object must have algorithms for all of the essential internal methods. However, all objects do not necessarily use the same algorithms for those methods.

An ordinary object is an object that satisfies all of the following criteria:

@@ -3700,7 +3701,7 @@

The Reference Record Specification Type

[[ReferencedName]] - String or Symbol + String, Symbol, or Private Name The name of the binding. Always a String if [[Base]] value is an Environment Record. @@ -3717,7 +3718,7 @@

The Reference Record Specification Type

-

The following abstract operations are used in this specification to operate upon References:

+

The following abstract operations are used in this specification to operate upon Reference Records:

IsPropertyReference ( _V_ )

@@ -3747,6 +3748,15 @@

IsSuperReference ( _V_ )

+ +

IsPrivateReference ( _V_ )

+

The abstract operation IsPrivateReference takes argument _V_. It performs the following steps when called:

+ + 1. Assert: _V_ is a Reference Record. + 1. If _V_.[[ReferencedName]] is a Private Name, return *true*; otherwise return *false*. + +
+

GetValue ( _V_ )

The abstract operation GetValue takes argument _V_. It performs the following steps when called:

@@ -3756,6 +3766,8 @@

GetValue ( _V_ )

1. If IsUnresolvableReference(_V_) is *true*, throw a *ReferenceError* exception. 1. If IsPropertyReference(_V_) is *true*, then 1. [id="step-getvalue-toobject"] Let _baseObj_ be ! ToObject(_V_.[[Base]]). + 1. If IsPrivateReference(_V_) is *true*, then + 1. Return ? PrivateGet(_V_.[[ReferencedName]], _baseObj_). 1. Return ? _baseObj_.[[Get]](_V_.[[ReferencedName]], GetThisValue(_V_)). 1. Else, 1. Let _base_ be _V_.[[Base]]. @@ -3780,6 +3792,8 @@

PutValue ( _V_, _W_ )

1. Return ? Set(_globalObj_, _V_.[[ReferencedName]], _W_, *false*). 1. If IsPropertyReference(_V_) is *true*, then 1. [id="step-putvalue-toobject"] Let _baseObj_ be ! ToObject(_V_.[[Base]]). + 1. If IsPrivateReference(_V_) is *true*, then + 1. Return ? PrivateSet(_V_.[[ReferencedName]], _baseObj_, _W_). 1. Let _succeeded_ be ? _baseObj_.[[Set]](_V_.[[ReferencedName]], _W_, GetThisValue(_V_)). 1. If _succeeded_ is *false* and _V_.[[Strict]] is *true*, throw a *TypeError* exception. 1. Return. @@ -3815,6 +3829,17 @@

InitializeReferencedBinding ( _V_, _W_ )

1. Return _base_.InitializeBinding(_V_.[[ReferencedName]], _W_).
+ + +

MakePrivateReference ( _baseValue_, _privateIdentifier_ )

+

The abstract operation MakePrivateReference takes arguments _baseValue_ (an ECMAScript language value) and _privateIdentifier_ (a String). It performs the following steps when called:

+ + 1. Let _privEnv_ be the running execution context's PrivateEnvironment. + 1. Assert: _privEnv_ is not *null*. + 1. Let _privateName_ be ! ResolvePrivateIdentifier(_privEnv_, _privateIdentifier_). + 1. Return the Reference Record { [[Base]]: _baseValue_, [[ReferencedName]]: _privateName_, [[Strict]]: *true*, [[ThisValue]]: ~empty~ }. + +
@@ -4020,6 +4045,152 @@

CopyDataBlockBytes ( _toBlock_, _toIndex_, _fromBlock_, _fromIndex_, _count_ + + +

The PrivateElement Specification Type

+

The PrivateElement type is a Record used in the specification of private class fields, methods, and accessors. Although Property Descriptors are not used for private elements, private fields behave similarly to non-configurable, non-enumerable, writable data properties, private methods behave similarly to non-configurable, non-enumerable, non-writable data properties, and private accessors behave similarly to non-configurable, non-enumerable accessor properties.

+

Values of the PrivateElement type are Record values whose fields are defined by . Such values are referred to as PrivateElements.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field Name + + Values of the [[Kind]] field for which it is present + + Value + + Meaning +
+ [[Key]] + + All + + a Private Name + + The name of the field, method, or accessor. +
+ [[Kind]] + + All + + ~field~, ~method~, or ~accessor~ + + The kind of the element. +
+ [[Value]] + + ~field~ and ~method~ + + any ECMAScript language value + + The value of the field. +
+ [[Get]] + + ~accessor~ + + Function or Undefined + + The getter for a private accessor. +
+ [[Set]] + + ~accessor~ + + Function or Undefined + + The setter for a private accessor. +
+
+
+ + +

The ClassFieldDefinition Record Specification Type

+

The ClassFieldDefinition type is a Record used in the specification of class fields.

+

Values of the ClassFieldDefinition type are Record values whose fields are defined by . Such values are referred to as ClassFieldDefinition Records.

+ + + + + + + + + + + + + + + + + + + +
+ Field Name + + Value + + Meaning +
+ [[Name]] + + a Private Name, a String value, or a Symbol value. + + The name of the field. +
+ [[Initializer]] + + an ECMAScript function object, or ~empty~ + + The initializer of the field, if any. +
+
+
+ + +

Private Names

+

The Private Name specification type is used to describe a globally unique value (one which differs from any other Private Name, even if they are otherwise indistinguishable) which represents the key of a private class element (field, method, or accessor). Each Private Name has an associated immutable [[Description]] which is a String value. A Private Name may be installed on any ECMAScript object with PrivateFieldAdd or PrivateMethodOrAccessorAdd, and then read or written using PrivateGet and PrivateSet.

+
@@ -5023,6 +5194,16 @@

IsStringPrefix ( _p_, _q_ )

+ +

HasIdentity ( _argument_ )

+

The abstract operation HasIdentity takes argument _argument_ (an ECMAScript language value). It determines if _argument_ is considered to have a unique identity, enabling _argument_ to be a key of a WeakMap or entry in a WeakSet. This operation performs the following steps when called:

+ + 1. If Type(_argument_) is Object, return *true*. + 1. If Type(_argument_) is Symbol, return *true*. + 1. Return *false*. + +
+

SameValue ( _x_, _y_ )

The abstract operation SameValue takes arguments _x_ (an ECMAScript language value) and _y_ (an ECMAScript language value) and returns a completion record whose [[Type]] is ~normal~ and whose [[Value]] is a Boolean. It performs the following steps when called:

@@ -5546,6 +5727,102 @@

CopyDataProperties ( _target_, _source_, _excludedItems_ )

The target passed in here is always a newly created object which is not directly accessible in case of an error being thrown.

+ + +

PrivateElementFind ( _P_, _O_ )

+

The abstract operation PrivateElementFind takes arguments _P_ (a Private Name) and _O_ (an Object). It performs the following steps when called:

+ + 1. If _O_.[[PrivateElements]] contains a PrivateElement whose [[Key]] is _P_, then + 1. Let _entry_ be that PrivateElement. + 1. Return _entry_. + 1. Return ~empty~. + +
+ + +

PrivateFieldAdd ( _P_, _O_, _value_ )

+

The abstract operation PrivateFieldAdd takes arguments _P_ (a Private Name), _O_ (an Object), and _value_ (an ECMAScript language value). It performs the following steps when called:

+ + 1. Let _entry_ be ! PrivateElementFind(_P_, _O_). + 1. If _entry_ is not ~empty~, throw a *TypeError* exception. + 1. Append PrivateElement { [[Key]]: _P_, [[Kind]]: ~field~, [[Value]]: _value_ } to _O_.[[PrivateElements]]. + +
+ + +

PrivateMethodOrAccessorAdd ( _method_, _O_ )

+

The abstract operation PrivateMethodOrAccessorAdd takes arguments _method_ (a PrivateElement) and _O_ (an Object). It performs the following steps when called:

+ + 1. Assert: _method_.[[Kind]] is either ~method~ or ~accessor~. + 1. Let _entry_ be ! PrivateElementFind(_method_.[[Key]], _O_). + 1. If _entry_ is not ~empty~, throw a *TypeError* exception. + 1. Append _method_ to _O_.[[PrivateElements]]. + 1. NOTE: the values for private methods and accessors are shared across instances. This step does not create a new copy of the method or accessor. + +
+ + +

PrivateGet ( _P_, _O_ )

+

The abstract operation PrivateGet takes arguments _P_ (a Private Name) and _O_ (an Object). It performs the following steps when called:

+ + 1. Let _entry_ be ! PrivateElementFind(_P_, _O_). + 1. If _entry_ is ~empty~, throw a *TypeError* exception. + 1. If _entry_.[[Kind]] is ~field~ or ~method~, then + 1. Return _entry_.[[Value]]. + 1. Assert: _entry_.[[Kind]] is ~accessor~. + 1. If _entry_.[[Get]] is *undefined*, throw a *TypeError* exception. + 1. Let _getter_ be _entry_.[[Get]]. + 1. Return ? Call(_getter_, _O_). + +
+ + +

PrivateSet ( _P_, _O_, _value_ )

+

The abstract operation PrivateSet takes arguments _P_ (a Private Name), _O_ (an Object), and _value_ (an ECMAScript language value). It performs the following steps when called:

+ + 1. Let _entry_ be ! PrivateElementFind(_P_, _O_). + 1. If _entry_ is ~empty~, throw a *TypeError* exception. + 1. If _entry_.[[Kind]] is ~field~, then + 1. Set _entry_.[[Value]] to _value_. + 1. Else if _entry_.[[Kind]] is ~method~, then + 1. Throw a *TypeError* exception. + 1. Else, + 1. Assert: _entry_.[[Kind]] is ~accessor~. + 1. If _entry_.[[Set]] is *undefined*, throw a *TypeError* exception. + 1. Let _setter_ be _entry_.[[Set]]. + 1. Perform ? Call(_setter_, _O_, « _value_ »). + +
+ + +

DefineField ( _receiver_, _fieldRecord_ )

+

The abstract operation DefineField takes arguments _receiver_ (an Object) and _fieldRecord_ (a ClassFieldDefinition Record). It performs the following steps when called:

+ + 1. Let _fieldName_ be _fieldRecord_.[[Name]]. + 1. Let _initializer_ be _fieldRecord_.[[Initializer]]. + 1. If _initializer_ is not ~empty~, then + 1. Let _initValue_ be ? Call(_initializer_, _receiver_). + 1. Else, let _initValue_ be *undefined*. + 1. If _fieldName_ is a Private Name, then + 1. Perform ? PrivateFieldAdd(_fieldName_, _receiver_, _initValue_). + 1. Else, + 1. Assert: ! IsPropertyKey(_fieldName_) is *true*. + 1. Perform ? CreateDataPropertyOrThrow(_receiver_, _fieldName_, _initValue_). + +
+ + +

InitializeInstanceElements ( _O_, _constructor_ )

+

The abstract operation InitializeInstanceElements takes arguments _O_ (an Object) and _constructor_ (an ECMAScript function object). It performs the following steps when called:

+ + 1. Let _methods_ be the value of _constructor_.[[PrivateMethods]]. + 1. For each PrivateElement _method_ of _methods_, do + 1. Perform ? PrivateMethodOrAccessorAdd(_method_, _O_). + 1. Let _fields_ be the value of _constructor_.[[Fields]]. + 1. For each element _fieldRecord_ of _fields_, do + 1. Perform ? DefineField(_O_, _fieldRecord_). + +
@@ -7406,6 +7683,7 @@

Static Semantics: IsFunctionDefinition

SuperProperty MetaProperty `new` MemberExpression Arguments + MemberExpression `.` PrivateIdentifier NewExpression : `new` NewExpression @@ -7557,6 +7835,7 @@

Static Semantics: IsIdentifierRef

SuperProperty MetaProperty `new` MemberExpression Arguments + MemberExpression `.` PrivateIdentifier NewExpression : `new` NewExpression @@ -7755,7 +8034,11 @@

Static Semantics: Contains

Static Semantics: ComputedPropertyContains

With parameter _symbol_.

- PropertyName : LiteralPropertyName + + ClassElementName : PrivateIdentifier + + PropertyName : LiteralPropertyName + 1. Return *false*. @@ -7765,20 +8048,20 @@

Static Semantics: ComputedPropertyContains

MethodDefinition : - PropertyName `(` UniqueFormalParameters `)` `{` FunctionBody `}` - `get` PropertyName `(` `)` `{` FunctionBody `}` - `set` PropertyName `(` PropertySetParameterList `)` `{` FunctionBody `}` + ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}` + `get` ClassElementName `(` `)` `{` FunctionBody `}` + `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}` - 1. Return the result of ComputedPropertyContains for |PropertyName| with argument _symbol_. + 1. Return the result of ComputedPropertyContains for |ClassElementName| with argument _symbol_. - GeneratorMethod : `*` PropertyName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` + GeneratorMethod : `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` - 1. Return the result of ComputedPropertyContains for |PropertyName| with argument _symbol_. + 1. Return the result of ComputedPropertyContains for |ClassElementName| with argument _symbol_. - AsyncGeneratorMethod : `async` `*` PropertyName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` + AsyncGeneratorMethod : `async` `*` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` - 1. Return the result of ComputedPropertyContains for |PropertyName| with argument _symbol_. + 1. Return the result of ComputedPropertyContains for |ClassElementName| with argument _symbol_. ClassElementList : ClassElementList ClassElement @@ -7791,10 +8074,16 @@

Static Semantics: ComputedPropertyContains

1. Return *false*.
- AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` + AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` + + + 1. Return the result of ComputedPropertyContains for |ClassElementName| with argument _symbol_. + + + FieldDefinition : ClassElementName Initializer? - 1. Return the result of ComputedPropertyContains for |PropertyName| with argument _symbol_. + 1. Return the result of ComputedPropertyContains for |ClassElementName| with argument _symbol_.
@@ -7805,14 +8094,14 @@

Miscellaneous

Runtime Semantics: InstantiateFunctionObject

-

With parameter _scope_.

+

With parameters _scope_ and _privateScope_.

FunctionDeclaration : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}` `function` `(` FormalParameters `)` `{` FunctionBody `}` - 1. Return ? InstantiateOrdinaryFunctionObject of |FunctionDeclaration| with argument _scope_. + 1. Return ? InstantiateOrdinaryFunctionObject of |FunctionDeclaration| with arguments _scope_ and _privateScope_. GeneratorDeclaration : @@ -7820,7 +8109,7 @@

Runtime Semantics: InstantiateFunctionObject

`function` `*` `(` FormalParameters `)` `{` GeneratorBody `}`
- 1. Return ? InstantiateGeneratorFunctionObject of |GeneratorDeclaration| with argument _scope_. + 1. Return ? InstantiateGeneratorFunctionObject of |GeneratorDeclaration| with arguments _scope_ and _privateScope_. AsyncGeneratorDeclaration : @@ -7828,7 +8117,7 @@

Runtime Semantics: InstantiateFunctionObject

`async` `function` `*` `(` FormalParameters `)` `{` AsyncGeneratorBody `}`
- 1. Return ? InstantiateAsyncGeneratorFunctionObject of |AsyncGeneratorDeclaration| with argument _scope_. + 1. Return ? InstantiateAsyncGeneratorFunctionObject of |AsyncGeneratorDeclaration| with arguments _scope_ and _privateScope_. AsyncFunctionDeclaration : @@ -7836,7 +8125,7 @@

Runtime Semantics: InstantiateFunctionObject

`async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}`
- 1. Return ? InstantiateAsyncFunctionObject of |AsyncFunctionDeclaration| with argument _scope_. + 1. Return ? InstantiateAsyncFunctionObject of |AsyncFunctionDeclaration| with arguments _scope_ and _privateScope_.
@@ -8095,11 +8384,13 @@

Static Semantics: AssignmentTargetType

CallExpression : CallExpression `[` Expression `]` CallExpression `.` IdentifierName + CallExpression `.` PrivateIdentifier MemberExpression : MemberExpression `[` Expression `]` MemberExpression `.` IdentifierName SuperProperty + MemberExpression `.` PrivateIdentifier 1. Return ~simple~. @@ -8266,30 +8557,42 @@

Static Semantics: PropName

MethodDefinition : - PropertyName `(` UniqueFormalParameters `)` `{` FunctionBody `}` - `get` PropertyName `(` `)` `{` FunctionBody `}` - `set` PropertyName `(` PropertySetParameterList `)` `{` FunctionBody `}` + ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}` + `get` ClassElementName `(` `)` `{` FunctionBody `}` + `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}` - 1. Return PropName of |PropertyName|. + 1. Return PropName of |ClassElementName|. - GeneratorMethod : `*` PropertyName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` + GeneratorMethod : `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` - 1. Return PropName of |PropertyName|. + 1. Return PropName of |ClassElementName|. - AsyncGeneratorMethod : `async` `*` PropertyName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` + AsyncGeneratorMethod : `async` `*` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` - 1. Return PropName of |PropertyName|. + 1. Return PropName of |ClassElementName|. ClassElement : `;` 1. Return ~empty~. - AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` + AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` - 1. Return PropName of |PropertyName|. + 1. Return PropName of |ClassElementName|. + + + FieldDefinition : ClassElementName Initializer? + + + 1. Return PropName of |ClassElementName|. + + + ClassElementName : PrivateIdentifier + + + 1. Return ~empty~. @@ -9416,6 +9719,82 @@

NewModuleEnvironment ( _E_ )

+ +

PrivateEnvironment Records

+

A PrivateEnvironment Record is a specification mechanism used to track Private Names based upon the lexical nesting structure of |ClassDeclaration|s and |ClassExpression|s in ECMAScript code. They are similar to, but distinct from, Environment Records. Each PrivateEnvironment Record is associated with a |ClassDeclaration| or |ClassExpression|. Each time such a class is evaluated, a new PrivateEnvironment Record is created to record the Private Names declared by that class.

+

Each PrivateEnvironment Record has the fields defined in .

+ + + + + + + + + + + + + + + + + + + + + +
+ Field Name + + Value Type + + Meaning +
+ [[OuterPrivateEnvironment]] + + PrivateEnvironment Record | *null* + + The PrivateEnvironment Record of the nearest containing class. *null* if the class with which this PrivateEnvironment Record is associated is not contained in any other class. +
+ [[Names]] + + List of Private Names. + + The Private Names declared by this class. +
+
+ + +

PrivateEnvironment Record Operations

+

The following abstract operations are used in this specification to operate upon PrivateEnvironment Records:

+ + +

NewPrivateEnvironment ( _outerPrivEnv_ )

+

The abstract operation NewPrivateEnvironment takes argument _outerPrivEnv_ (a PrivateEnvironment Record or *null*). It performs the following steps when called:

+ + 1. Let _names_ be a new empty List. + 1. Return the PrivateEnvironment Record { [[OuterPrivateEnvironment]]: _outerPrivEnv_, [[Names]]: _names_ }. + +
+ + +

ResolvePrivateIdentifier ( _privEnv_, _identifier_ )

+

The abstract operation ResolvePrivateIdentifier takes arguments _privEnv_ (a PrivateEnvironment Record) and _identifier_ (a String). It performs the following steps when called:

+ + 1. Let _names_ be _privEnv_.[[Names]]. + 1. If _names_ contains a Private Name whose [[Description]] is _identifier_, then + 1. Let _name_ be that Private Name. + 1. Return _name_. + 1. Else, + 1. Let _outerPrivEnv_ be _privEnv_.[[OuterPrivateEnvironment]]. + 1. Assert: _outerPrivEnv_ is not *null*. + 1. Return ResolvePrivateIdentifier(_outerPrivEnv_, _identifier_). + +
+
+
+

Realms

Before it is evaluated, all ECMAScript code must be associated with a realm. Conceptually, a realm consists of a set of intrinsic objects, an ECMAScript global environment, all of the ECMAScript code that is loaded within the scope of that global environment, and other associated state and resources.

@@ -9630,6 +10009,14 @@

Execution Contexts

Identifies the Environment Record that holds bindings created by |VariableStatement|s within this execution context. + + + PrivateEnvironment + + + Identifies the PrivateEnvironment Record that holds Private Names created by |ClassElement|s in the nearest containing class. *null* if there is no containing class. + + @@ -10064,11 +10451,11 @@

Forward Progress

-

Processing Model of WeakRef and FinalizationRegistry Objects

+

Processing Model of WeakRef and FinalizationRegistry Identity Values

Objectives

-

This specification does not make any guarantees that any object will be garbage collected. Objects which are not live may be released after long periods of time, or never at all. For this reason, this specification uses the term "may" when describing behaviour triggered by garbage collection.

+

This specification does not make any guarantees that any object will be garbage collected. Objects or symbols which are not live may be released after long periods of time, or never at all. For this reason, this specification uses the term "may" when describing behaviour triggered by garbage collection.

The semantics of WeakRef and FinalizationRegistry objects is based on two operations which happen at particular points in time:

@@ -10090,38 +10477,41 @@

Objectives

Liveness

-

For some set of objects _S_, a hypothetical WeakRef-oblivious execution with respect to _S_ is an execution whereby the abstract operation WeakRefDeref of a WeakRef whose referent is an element of _S_ always returns *undefined*.

+

For some set of symbols and objects _S_, a hypothetical WeakRef-oblivious execution with respect to _S_ is an execution whereby the abstract operation WeakRefDeref of a WeakRef whose referent is an element of _S_ always returns *undefined*.

- WeakRef-obliviousness, together with liveness, capture two notions. One, that a WeakRef itself does not keep an object alive. Two, that cycles in liveness does not imply that an object is live. To be concrete, if determining _obj_'s liveness depends on determining the liveness of another WeakRef referent, _obj2_, _obj2_'s liveness cannot assume _obj_'s liveness, which would be circular reasoning. + WeakRef-obliviousness, together with liveness, capture two notions. One, that a WeakRef itself does not keep a reference alive. Two, that cycles in liveness does not imply that a reference is live. To be concrete, if determining _ref_'s liveness depends on determining the liveness of another WeakRef referent, _ref2_, _ref2_'s liveness cannot assume _ref_'s liveness, which would be circular reasoning. - WeakRef-obliviousness is defined on sets of objects instead of individual objects to account for cycles. If it were defined on individual objects, then an object in a cycle will be considered live even though its Object value is only observed via WeakRefs of other objects in the cycle. + WeakRef-obliviousness is defined on sets of symbols or objects instead of individual references to account for cycles. If it were defined on individual values, then a reference in a cycle will be considered live even though its respective value is only observed via WeakRefs of other references in the cycle. - Colloquially, we say that an individual object is live if every set of objects containing it is live. + Colloquially, we say that an individual symbol or object is live if every set of symbols and/or objects containing it is live. -

At any point during evaluation, a set of objects _S_ is considered live if either of the following conditions is met:

+

At any point during evaluation, a set of symbols and/or _S_ is considered live if either of the following conditions is met:

  • Any element in _S_ is included in any agent's [[KeptAlive]] List.
  • - There exists a valid future hypothetical WeakRef-oblivious execution with respect to _S_ that observes the Object value of any object in _S_. + There exists a valid future hypothetical WeakRef-oblivious execution with respect to _S_ that observes the value of any symbol or object in _S_.
- The second condition above intends to capture the intuition that an object is live if its identity is observable via non-WeakRef means. An object's identity may be observed by observing a strict equality comparison between objects or observing the object being used as key in a Map. + The second condition above intends to capture the intuition that a reference is live if its identity is observable via non-WeakRef means. An reference value's identity may be observed by observing a strict equality comparison or observing the value being used as key in a Map. -

Presence of an object in a field, an internal slot, or a property does not imply that the object is live. For example if the object in question is never passed back to the program, then it cannot be observed.

+

Presence of a symbol or an object in a field, an internal slot, or a property does not imply that the reference is live. For example if the reference in question is never passed back to the program, then it cannot be observed.

This is the case for keys in a WeakMap, members of a WeakSet, as well as the [[WeakRefTarget]] and [[UnregisterToken]] fields of a FinalizationRegistry Cell record.

The above definition implies that, if a key in a WeakMap is not live, then its corresponding value is not necessarily live either.

+ + Presence of a symbol in the GlobalSymbolRegistry List might keep the reference alive. Symbol values might have their liveness compromised if contained in the GlobalSymbolRegistry List as it is globablly avaialble and shared by all realms. + Liveness is the lower bound for guaranteeing which WeakRefs engines must not empty. Liveness as defined here is undecidable. In practice, engines use conservative approximations such as reachability. There is expected to be significant implementation leeway. @@ -10130,20 +10520,20 @@

Liveness

Execution

-

At any time, if a set of objects _S_ is not live, an ECMAScript implementation may perform the following steps atomically:

+

At any time, if a set of objects and/or symbols _S_ is not live, an ECMAScript implementation may perform the following steps atomically:

- 1. For each element _obj_ of _S_, do - 1. For each WeakRef _ref_ such that _ref_.[[WeakRefTarget]] is _obj_, do + 1. For each element _value_ of _S_, do + 1. For each WeakRef _ref_ such that _ref_.[[WeakRefTarget]] is _value_, do 1. Set _ref_.[[WeakRefTarget]] to ~empty~. - 1. For each FinalizationRegistry _fg_ such that _fg_.[[Cells]] contains a Record _cell_ such that _cell_.[[WeakRefTarget]] is _obj_, do + 1. For each FinalizationRegistry _fg_ such that _fg_.[[Cells]] contains a Record _cell_ such that _cell_.[[WeakRefTarget]] is _value_, do 1. Set _cell_.[[WeakRefTarget]] to ~empty~. 1. Optionally, perform ! HostEnqueueFinalizationRegistryCleanupJob(_fg_). - 1. For each WeakMap _map_ such that _map_.[[WeakMapData]] contains a Record _r_ such that _r_.[[Key]] is _obj_, do + 1. For each WeakMap _map_ such that _map_.[[WeakMapData]] contains a Record _r_ such that _r_.[[Key]] is _value_, do 1. Set _r_.[[Key]] to ~empty~. 1. Set _r_.[[Value]] to ~empty~. - 1. For each WeakSet _set_ such that _set_.[[WeakSetData]] contains _obj_, do - 1. Replace the element of _set_.[[WeakSetData]] whose value is _obj_ with an element whose value is ~empty~. + 1. For each WeakSet _set_ such that _set_.[[WeakSetData]] contains _value_, do + 1. Replace the element of _set_.[[WeakSetData]] whose value is _value_ with an element whose value is ~empty~. @@ -10156,7 +10546,7 @@

Execution

Because calling HostEnqueueFinalizationRegistryCleanupJob is optional, registered objects in a FinalizationRegistry do not necessarily hold that FinalizationRegistry live. Implementations may omit FinalizationRegistry callbacks for any reason, e.g., if the FinalizationRegistry itself becomes dead, or if the application is shutting down.

-

Implementations are not obligated to empty WeakRefs for maximal sets of non-live objects.

+

Implementations are not obligated to empty WeakRefs for maximal sets of non-live objects ir symbols.

If an implementation chooses a non-live set _S_ in which to empty WeakRefs, it must empty WeakRefs for all objects in _S_ simultaneously. In other words, an implementation must not empty a WeakRef pointing to an object _obj_ without emptying out other WeakRefs that, if not emptied, could result in an execution that observes the Object value of _obj_.

@@ -10629,6 +11019,17 @@

ECMAScript Function Objects

The Environment Record that the function was closed over. Used as the outer environment when evaluating the code of the function. + + + [[PrivateEnvironment]] + + + PrivateEnvironment Record | *null* + + + The PrivateEnvironment Record for Private Names that the function was closed over. *null* if this function is not syntactically contained within a class. Used as the outer PrivateEnvironment for inner classes when evaluating the code of the function. + + [[FormalParameters]] @@ -10728,6 +11129,39 @@

ECMAScript Function Objects

The source text that defines the function. + + + [[Fields]] + + + List of ClassFieldDefinition Records + + + If the function is a class, this is a list of Records representing the non-static fields and corresponding initializers of the class. + + + + + [[PrivateMethods]] + + + List of PrivateElements + + + If the function is a class, this is a list representing the non-static private methods and accessors of the class. + + + + + [[ClassFieldInitializerName]] + + + String | Symbol | Private Name | ~empty~ + + + If the function is created as the initializer of a class field, the name to use for NamedEvaluation of the field; ~empty~ otherwise. + + [[IsClassConstructor]] @@ -10782,6 +11216,7 @@

PrepareForOrdinaryCall ( _F_, _newTarget_ )

1. Let _localEnv_ be NewFunctionEnvironment(_F_, _newTarget_). 1. Set the LexicalEnvironment of _calleeContext_ to _localEnv_. 1. Set the VariableEnvironment of _calleeContext_ to _localEnv_. + 1. Set the PrivateEnvironment of _calleeContext_ to _F_.[[PrivateEnvironment]]. 1. If _callerContext_ is not already suspended, suspend _callerContext_. 1. Push _calleeContext_ onto the execution context stack; _calleeContext_ is now the running execution context. 1. NOTE: Any exception objects produced after this point are associated with _calleeRealm_. @@ -10845,6 +11280,23 @@

Runtime Semantics: EvaluateBody

1. Return ? EvaluateAsyncConciseBody of |AsyncConciseBody| with arguments _functionObject_ and _argumentsList_. + + Initializer : + `=` AssignmentExpression + + + 1. Assert: _argumentsList_ is empty. + 1. Assert: _functionObject_.[[ClassFieldInitializerName]] is not ~empty~. + 1. If IsAnonymousFunctionDefinition(|AssignmentExpression|) is *true*, then + 1. Let _value_ be NamedEvaluation of |Initializer| with argument _functionObject_.[[ClassFieldInitializerName]]. + 1. Else, + 1. Let _rhs_ be the result of evaluating |AssignmentExpression|. + 1. Let _value_ be ? GetValue(_rhs_). + 1. Return Completion { [[Type]]: ~return~, [[Value]]: _value_, [[Target]]: ~empty~ }. + + +

Even though field initializers constitute a function boundary, calling FunctionDeclarationInstantiation does not have any observable effect and so is omitted.

+
@@ -10868,7 +11320,12 @@

[[Construct]] ( _argumentsList_, _newTarget_ )

1. Let _thisArgument_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%Object.prototype%"*). 1. Let _calleeContext_ be PrepareForOrdinaryCall(_F_, _newTarget_). 1. Assert: _calleeContext_ is now the running execution context. - 1. If _kind_ is ~base~, perform OrdinaryCallBindThis(_F_, _calleeContext_, _thisArgument_). + 1. If _kind_ is ~base~, then + 1. Perform OrdinaryCallBindThis(_F_, _calleeContext_, _thisArgument_). + 1. Let _initializeResult_ be InitializeInstanceElements(_thisArgument_, _F_). + 1. If _initializeResult_ is an abrupt completion, then + 1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context. + 1. Return Completion(_initializeResult_). 1. Let _constructorEnv_ be the LexicalEnvironment of _calleeContext_. 1. Let _result_ be OrdinaryCallEvaluateBody(_F_, _argumentsList_). 1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context. @@ -10882,8 +11339,8 @@

[[Construct]] ( _argumentsList_, _newTarget_ )

-

OrdinaryFunctionCreate ( _functionPrototype_, _sourceText_, _ParameterList_, _Body_, _thisMode_, _Scope_ )

-

The abstract operation OrdinaryFunctionCreate takes arguments _functionPrototype_ (an Object), _sourceText_ (a sequence of Unicode code points), _ParameterList_ (a Parse Node), _Body_ (a Parse Node), _thisMode_ (either ~lexical-this~ or ~non-lexical-this~), and _Scope_ (an Environment Record). _sourceText_ is the source text of the syntactic definition of the function to be created. It performs the following steps when called:

+

OrdinaryFunctionCreate ( _functionPrototype_, _sourceText_, _ParameterList_, _Body_, _thisMode_, _Scope_, _PrivateScope_ )

+

The abstract operation OrdinaryFunctionCreate takes arguments _functionPrototype_ (an Object), _sourceText_ (a sequence of Unicode code points), _ParameterList_ (a Parse Node), _Body_ (a Parse Node), _thisMode_ (either ~lexical-this~ or ~non-lexical-this~), _Scope_ (an Environment Record), and _PrivateScope_ (a PrivateEnvironment Record or *null*). _sourceText_ is the source text of the syntactic definition of the function to be created. It performs the following steps when called:

1. Assert: Type(_functionPrototype_) is Object. 1. Let _internalSlotsList_ be the internal slots listed in . @@ -10899,9 +11356,11 @@

OrdinaryFunctionCreate ( _functionPrototype_, _sourceText_, _ParameterList_, 1. Else, set _F_.[[ThisMode]] to ~global~. 1. Set _F_.[[IsClassConstructor]] to *false*. 1. Set _F_.[[Environment]] to _Scope_. + 1. Set _F_.[[PrivateEnvironment]] to _PrivateScope_. 1. Set _F_.[[ScriptOrModule]] to GetActiveScriptOrModule(). 1. Set _F_.[[Realm]] to the current Realm Record. 1. Set _F_.[[HomeObject]] to *undefined*. + 1. Set _F_.[[ClassFieldInitializerName]] to ~empty~. 1. Let _len_ be the ExpectedArgumentCount of _ParameterList_. 1. Perform ! SetFunctionLength(_F_, _len_). 1. Return _F_. @@ -10971,17 +11430,31 @@

MakeMethod ( _F_, _homeObject_ )

+ +

DefineMethodProperty ( _key_, _homeObject_, _closure_, _enumerable_ )

+

The abstract operation DefineMethodProperty takes arguments _key_ (a property key or Private Name), _homeObject_ (an Object), _closure_ (a function object), and _enumerable_ (a Boolean). It performs the following steps when called:

+ + 1. Perform ! SetFunctionName(_closure_, _key_). + 1. If _key_ is a Private Name, then + 1. Return PrivateElement { [[Key]]: _key_, [[Kind]]: ~method~, [[Value]]: _closure_ }. + 1. Else, + 1. Let _desc_ be the PropertyDescriptor { [[Value]]: _closure_, [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }. + 1. Perform ? DefinePropertyOrThrow(_homeObject_, _key_, _desc_). + 1. Return ~empty~. + +
+

SetFunctionName ( _F_, _name_ [ , _prefix_ ] )

-

The abstract operation SetFunctionName takes arguments _F_ (a function object) and _name_ (a property key) and optional argument _prefix_ (a String). It adds a *"name"* property to _F_. It performs the following steps when called:

+

The abstract operation SetFunctionName takes arguments _F_ (a function object) and _name_ (a property key or Private Name) and optional argument _prefix_ (a String). It adds a *"name"* property to _F_. It performs the following steps when called:

1. Assert: _F_ is an extensible object that does not have a *"name"* own property. - 1. Assert: Type(_name_) is either Symbol or String. - 1. Assert: If _prefix_ is present, then Type(_prefix_) is String. 1. If Type(_name_) is Symbol, then 1. Let _description_ be _name_'s [[Description]] value. 1. If _description_ is *undefined*, set _name_ to the empty String. 1. Else, set _name_ to the string-concatenation of *"["*, _description_, and *"]"*. + 1. Else if _name_ is a Private Name, then + 1. Set _name_ to _name_.[[Description]]. 1. If _F_ has an [[InitialName]] internal slot, then 1. Set _F_.[[InitialName]] to _name_. 1. If _prefix_ is present, then @@ -11115,9 +11588,10 @@

FunctionDeclarationInstantiation ( _func_, _argumentsList_ )

1. Perform ! _lexEnv_.CreateImmutableBinding(_dn_, *true*). 1. Else, 1. Perform ! _lexEnv_.CreateMutableBinding(_dn_, *false*). + 1. Let _privateEnv_ be the PrivateEnvironment of _calleeContext_. 1. For each Parse Node _f_ of _functionsToInitialize_, do 1. Let _fn_ be the sole element of the BoundNames of _f_. - 1. Let _fo_ be InstantiateFunctionObject of _f_ with argument _lexEnv_. + 1. Let _fo_ be InstantiateFunctionObject of _f_ with arguments _lexEnv_ and _privateEnv_. 1. Perform ! _varEnv_.SetMutableBinding(_fn_, _fo_, *false*). 1. Return NormalCompletion(~empty~).
@@ -13315,6 +13789,7 @@

Syntax

CommonToken :: IdentifierName + PrivateIdentifier Punctuator NumericLiteral StringLiteral @@ -13335,6 +13810,9 @@

Names and Keywords

Two |IdentifierName|s that are canonically equivalent according to the Unicode standard are not equal unless, after replacement of each |UnicodeEscapeSequence|, they are represented by the exact same sequence of code points.

Syntax

+ PrivateIdentifier :: + `#` IdentifierName + IdentifierName :: IdentifierStart IdentifierName IdentifierPart @@ -14722,6 +15200,13 @@

Static Semantics: StringValue

1. Return the StringValue of |IdentifierName|. + + PrivateIdentifier :: + `#` IdentifierName + + + 1. Return the string-concatenation of 0x0023 (NUMBER SIGN) and the StringValue of |IdentifierName|. +
@@ -15017,6 +15502,9 @@

Static Semantics: Early Errors

  • It is a Syntax Error if HasDirectSuper of |MethodDefinition| is *true*.
  • +
  • + It is a Syntax Error if PrivateBoundIdentifiers of |MethodDefinition| is not empty. +
  • In addition to describing an actual object initializer the |ObjectLiteral| productions are also used as a cover grammar for |ObjectAssignmentPattern| and may be recognized as part of a |CoverParenthesizedExpressionAndArrowParameterList|. When |ObjectLiteral| appears in a context where |ObjectAssignmentPattern| is required the following Early Error rules are not applied. In addition, they are not applied when initially parsing a |CoverParenthesizedExpressionAndArrowParameterList| or |CoverCallExpressionAndAsyncArrowHead|.

    PropertyDefinition : CoverInitializedName @@ -15136,25 +15624,25 @@

    Runtime Semantics: PropertyDefinitionEvaluation

    MethodDefinition : - PropertyName `(` UniqueFormalParameters `)` `{` FunctionBody `}` - `get` PropertyName `(` `)` `{` FunctionBody `}` - `set` PropertyName `(` PropertySetParameterList `)` `{` FunctionBody `}` + ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}` + `get` ClassElementName `(` `)` `{` FunctionBody `}` + `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}` 1. Return ? MethodDefinitionEvaluation of |MethodDefinition| with arguments _object_ and _enumerable_. - GeneratorMethod : `*` PropertyName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` + GeneratorMethod : `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}` 1. Return ? MethodDefinitionEvaluation of |GeneratorMethod| with arguments _object_ and _enumerable_. - AsyncGeneratorMethod : `async` `*` PropertyName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` + AsyncGeneratorMethod : `async` `*` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}` 1. Return ? MethodDefinitionEvaluation of |AsyncGeneratorMethod| with arguments _object_ and _enumerable_. - AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` + AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}` 1. Return ? MethodDefinitionEvaluation of |AsyncMethod| with arguments _object_ and _enumerable_. @@ -15509,6 +15997,7 @@

    Syntax

    SuperProperty[?Yield, ?Await] MetaProperty `new` MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] + MemberExpression[?Yield, ?Await] `.` PrivateIdentifier SuperProperty[Yield, Await] : `super` `[` Expression[+In, ?Yield, ?Await] `]` @@ -15536,6 +16025,7 @@

    Syntax

    CallExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]` CallExpression[?Yield, ?Await] `.` IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] + CallExpression[?Yield, ?Await] `.` PrivateIdentifier SuperCall[Yield, Await] : `super` Arguments[?Yield, ?Await] @@ -15564,10 +16054,12 @@

    Syntax

    `?.` `[` Expression[+In, ?Yield, ?Await] `]` `?.` IdentifierName `?.` TemplateLiteral[?Yield, ?Await, +Tagged] + `?.` PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]` OptionalChain[?Yield, ?Await] `.` IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] + OptionalChain[?Yield, ?Await] `.` PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] @@ -15676,6 +16168,14 @@

    Runtime Semantics: Evaluation

    1. If the code matched by this |MemberExpression| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*. 1. Return ? EvaluatePropertyAccessWithIdentifierKey(_baseValue_, |IdentifierName|, _strict_).
    + MemberExpression : MemberExpression `.` PrivateIdentifier + + 1. Let _baseReference_ be the result of evaluating |MemberExpression|. + 1. Let _baseValue_ be ? GetValue(_baseReference_). + 1. Let _bv_ be ? RequireObjectCoercible(_baseValue_). + 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|. + 1. Return ! MakePrivateReference(_bv_, _fieldNameString_). + CallExpression : CallExpression `[` Expression `]` 1. Let _baseReference_ be the result of evaluating |CallExpression|. @@ -15690,6 +16190,14 @@

    Runtime Semantics: Evaluation

    1. If the code matched by this |CallExpression| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*. 1. Return ? EvaluatePropertyAccessWithIdentifierKey(_baseValue_, |IdentifierName|, _strict_).
    + CallExpression : CallExpression `.` PrivateIdentifier + + 1. Let _baseReference_ be the result of evaluating |CallExpression|. + 1. Let _baseValue_ be ? GetValue(_baseReference_). + 1. Let _bv_ be ? RequireObjectCoercible(_baseValue_). + 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|. + 1. Return ! MakePrivateReference(_bv_, _fieldNameString_). +
    @@ -15839,7 +16347,11 @@

    Runtime Semantics: Evaluation

    1. If IsConstructor(_func_) is *false*, throw a *TypeError* exception. 1. Let _result_ be ? Construct(_func_, _argList_, _newTarget_). 1. Let _thisER_ be GetThisEnvironment(). - 1. Return ? _thisER_.BindThisValue(_result_). + 1. Perform ? _thisER_.BindThisValue(_result_). + 1. Let _F_ be _thisER_.[[FunctionObject]]. + 1. Assert: _F_ is an ECMAScript function object. + 1. Perform ? InitializeInstanceElements(_result_, _F_). + 1. Return _result_.
    @@ -16001,6 +16513,12 @@

    Runtime Semantics: ChainEvaluation

    1. If the code matched by this |OptionalChain| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*. 1. Return ? EvaluatePropertyAccessWithIdentifierKey(_baseValue_, |IdentifierName|, _strict_). + OptionalChain : `?.` PrivateIdentifier + + 1. Let _bv_ be ? RequireObjectCoercible(_baseValue_). + 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|. + 1. Return ! MakePrivateReference(_bv_, _fieldNameString_). + OptionalChain : OptionalChain Arguments 1. Let _optionalChain_ be |OptionalChain|. @@ -16026,6 +16544,15 @@

    Runtime Semantics: ChainEvaluation

    1. If the code matched by this |OptionalChain| is strict mode code, let _strict_ be *true*; else let _strict_ be *false*. 1. Return ? EvaluatePropertyAccessWithIdentifierKey(_newValue_, |IdentifierName|, _strict_).
    + OptionalChain : OptionalChain `.` PrivateIdentifier + + 1. Let _optionalChain_ be |OptionalChain|. + 1. Let _newReference_ be ? ChainEvaluation of _optionalChain_ with arguments _baseValue_ and _baseReference_. + 1. Let _newValue_ be ? GetValue(_newReference_). + 1. Let _nv_ be ? RequireObjectCoercible(_newValue_). + 1. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|. + 1. Return ! MakePrivateReference(_nv_, _fieldNameString_). + @@ -16262,7 +16789,7 @@

    Static Semantics: Early Errors

    UnaryExpression : `delete` UnaryExpression