diff --git a/spec.html b/spec.html
index 6362bcfc6e..4ec362299e 100644
--- a/spec.html
+++ b/spec.html
@@ -2371,6 +2371,17 @@
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 [[PrivateFields]], which is a List of PrivateField Records. This List represents the values of the private fields for the object. Initially, it is an empty List.
+ All objects have an internal slot named [[PrivateBrands]], which is a List of ECMAScript values which are used for checking to see if an object supports a private method or accessor. The entries in the list correspond to the "original prototype" (or, in the case of static methods, the "original constructor") which contained the private method or accessor. Initially, it is an empty List.
+
+ Although this specification uses logic of a [[PrivateBrands]] List which is held per-instance, the use of this list obeys certain invariants:
+
+
+ - Nothing is removed from the list; things are only added to the end.
+ - There is no way to distinguish different copies of the list.
+ - The list is mutable, but there are never any references to it outside of the particular object which holds it, so additions can be thought of as replacing the internal slot with another list which contains the new element.
+
+
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:
@@ -3766,7 +3777,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. |
@@ -3783,7 +3794,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_ )
@@ -3813,6 +3824,14 @@ IsSuperReference ( _V_ )
+
+ IsPrivateReference ( _V_ )
+
+ 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:
@@ -3822,6 +3841,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 ? PrivateFieldGet(_V_.[[ReferencedName]], _baseObj_).
1. Return ? _baseObj_.[[Get]](_V_.[[ReferencedName]], GetThisValue(_V_)).
1. Else,
1. Let _base_ be _V_.[[Base]].
@@ -3846,6 +3867,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 ? PrivateFieldSet(_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.
@@ -3881,6 +3904,17 @@ InitializeReferencedBinding ( _V_, _W_ )
1. Return _base_.InitializeBinding(_V_.[[ReferencedName]], _W_).
+
+
+ MakePrivateReference ( _baseValue_, _privateIdentifier_ )
+
+ 1. Let _env_ be the running execution context's PrivateEnvironment.
+ 1. Let _privateNameBinding_ be ! ResolveBinding(_privateIdentifier_, _env_).
+ 1. Let _privateName_ be ? GetValue(_privateNameBinding_).
+ 1. Assert: _privateName_ is a Private Name.
+ 1. Return the Reference Record { [[Base]]: _baseValue_, [[ReferencedName]]: _privateName_, [[Strict]]: *true*, [[ThisValue]]: ~empty~ }.
+
+
@@ -4086,6 +4120,220 @@ CopyDataBlockBytes ( _toBlock_, _toIndex_, _fromBlock_, _fromIndex_, _count_
+
+
+ The PrivateField Record Specification Type
+ The PrivateField type is a Record used in the specification of private class fields.
+ Values of the PrivateField type are Record values whose fields are defined as by . Such values are referred to as PrivateField Records.
+
+
+
+
+
+ Field Name
+ |
+
+ Value
+ |
+
+ Meaning
+ |
+
+
+
+ [[PrivateFieldName]]
+ |
+
+ a Private Name
+ |
+
+ The name of the field.
+ |
+
+
+
+ [[PrivateFieldValue]]
+ |
+
+ any ECMAScript language value
+ |
+
+ The value of the field.
+ |
+
+
+
+
+
+
+
+ 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 as 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.
+ |
+
+
+
+ [[IsAnonymousFunctionDefinition]]
+ |
+
+ Boolean
+ |
+
+ *true* if there is an Initializer and it is a function definition that does not bind a name, *false* otherwise.
+ |
+
+
+
+
+
+
+
+ Private Names
+ The Private Name specification type is used to describe a globally unique record which represents a private class element (field, method, or accessor). A Private Name may be installed on any ECMAScript object with PrivateFieldAdd, and then read or written using PrivateFieldGet and PrivateFieldSet.
+
+ Each Private Name holds the following information:
+
+
+
+
+
+ Field
+ |
+
+ Type
+ |
+
+ Values of the [[Kind]] field for which it is present
+ |
+
+ Description
+ |
+
+
+
+
+
+ [[Description]]
+ |
+
+ String
+ |
+
+ All
+ |
+
+ The string value passed to NewPrivateName when creating this Private Name.
+ |
+
+
+
+ [[Kind]]
+ |
+
+ ~field~, ~method~, or ~accessor~
+ |
+
+ All
+ |
+
+ Indicates what the private name is used for.
+ |
+
+
+
+ [[Brand]]
+ |
+
+ Object
+ |
+
+ ~method~ or ~accessor~
+ |
+
+ The "original" class of the private method or accessor; checked for in the [[PrivateBrands]] internal slot of instances before access is provided.
+ |
+
+
+
+ [[Value]]
+ |
+
+ Function
+ |
+
+ ~method~
+ |
+
+ The value of the private method.
+ |
+
+
+
+ [[Get]]
+ |
+
+ Function
+ |
+
+ ~accessor~
+ |
+
+ The getter for a private accessor.
+ |
+
+
+
+ [[Set]]
+ |
+
+ Function
+ |
+
+ ~accessor~
+ |
+
+ The setter for a private accessor.
+ |
+
+
+
+
+
@@ -5612,6 +5860,125 @@ 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.
+
+
+ NewPrivateName ( _description_ )
+
+ 1. Assert: Type(_description_) is String.
+ 1. Return a new unique Private Name whose [[Description]] value is _description_.
+
+
+
+
+ PrivateFieldFind ( _P_, _O_ )
+
+ 1. Assert: _P_ is a Private Name.
+ 1. Assert: Type(_O_) is Object.
+ 1. For each element _entry_ of _O_.[[PrivateFields]], do
+ 1. If _entry_.[[PrivateFieldName]] is _P_, return _entry_.
+ 1. Return ~empty~.
+
+
+
+
+ PrivateFieldAdd ( _P_, _O_, _value_ )
+
+ 1. Assert: _P_ is a Private Name.
+ 1. Assert: Type(_O_) is Object.
+ 1. Let _entry_ be ! PrivateFieldFind(_P_, _O_).
+ 1. If _entry_ is not ~empty~, throw a *TypeError* exception.
+ 1. Append PrivateField { [[PrivateFieldName]]: _P_, [[PrivateFieldValue]]: _value_ } to _O_.[[PrivateFields]].
+
+
+
+
+ PrivateFieldGet ( _P_, _O_ )
+
+ 1. Assert: _P_ is a Private Name.
+ 1. Assert: Type(_O_) is Object.
+ 1. If _P_.[[Kind]] is ~field~, then
+ 1. Let _entry_ be ! PrivateFieldFind(_P_, _O_).
+ 1. If _entry_ is ~empty~, throw a *TypeError* exception.
+ 1. Return _entry_.[[PrivateFieldValue]].
+ 1. Perform ? PrivateBrandCheck(_O_, _P_).
+ 1. If _P_.[[Kind]] is ~method~, then
+ 1. Return _P_.[[Value]].
+ 1. Assert: _P_.[[Kind]] is ~accessor~.
+ 1. If _P_ does not have a [[Get]] field, throw a *TypeError* exception.
+ 1. Let _getter_ be _P_.[[Get]].
+ 1. Return ? Call(_getter_, _O_).
+
+
+
+
+ PrivateFieldSet ( _P_, _O_, _value_ )
+
+ 1. Assert: _P_ is a Private Name.
+ 1. Assert: Type(_O_) is Object.
+ 1. If _P_.[[Kind]] is ~field~, then
+ 1. Let _entry_ be ! PrivateFieldFind(_P_, _O_).
+ 1. If _entry_ is ~empty~, throw a *TypeError* exception.
+ 1. Set _entry_.[[PrivateFieldValue]] to _value_.
+ 1. Return.
+ 1. If _P_.[[Kind]] is ~method~, throw a *TypeError* exception.
+ 1. Assert: _P_.[[Kind]] is ~accessor~.
+ 1. Perform ? PrivateBrandCheck(_O_, _P_).
+ 1. If _P_ does not have a [[Set]] field, throw a *TypeError* exception.
+ 1. Let _setter_ be _P_.[[Set]].
+ 1. Perform ? Call(_setter_, _O_, « _value_ &rqauo;).
+
+
+
+
+ DefineField ( _receiver_, _fieldRecord_ )
+
+ 1. Assert: Type(_receiver_) is Object.
+ 1. Assert: _fieldRecord_ is a ClassFieldDefinition Record.
+ 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 _fieldRecord_.[[IsAnonymousFunctionDefinition]] is *true*, then
+ 1. Let _hasNameProperty_ be ? HasOwnProperty(_initValue_, *"name"*).
+ 1. If _hasNameProperty_ is *false*, perform ! SetFunctionName(_initValue_, _fieldName_).
+ 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_ )
+
+ 1. Assert: Type(_O_) is Object.
+ 1. Assert: _constructor_ is an ECMAScript function object.
+ 1. If _constructor_.[[PrivateBrand]] is not *undefined*, then
+ 1. Perform ? PrivateBrandAdd(_O_, _constructor_.[[PrivateBrand]]).
+ 1. Let _fields_ be the value of _constructor_.[[Fields]].
+ 1. For each element _fieldRecord_ of _fields_, do
+ 1. Perform ? DefineField(_O_, _fieldRecord_).
+
+
+
+
+ PrivateBrandCheck ( _O_, _P_ )
+
+ 1. If _O_.[[PrivateBrands]] does not contain an entry _e_ such that SameValue(_e_, _P_.[[Brand]]) is *true*, then
+ 1. Throw a *TypeError* exception.
+
+
+
+
+ PrivateBrandAdd ( _O_, _brand_ )
+
+ 1. If _O_.[[PrivateBrands]] contains an entry _e_ such that SameValue(_e_, _brand_) is *true*, then
+ 1. Throw a *TypeError* exception.
+ 1. Append _brand_ to _O_.[[PrivateBrands]].
+
+
@@ -7484,6 +7851,7 @@ Static Semantics: IsFunctionDefinition
SuperProperty
MetaProperty
`new` MemberExpression Arguments
+ MemberExpression `.` PrivateIdentifier
NewExpression :
`new` NewExpression
@@ -7636,6 +8004,7 @@ Static Semantics: IsIdentifierRef
SuperProperty
MetaProperty
`new` MemberExpression Arguments
+ MemberExpression `.` PrivateIdentifier
NewExpression :
`new` NewExpression
@@ -7845,20 +8214,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
@@ -7871,10 +8240,16 @@ Static Semantics: ComputedPropertyContains
1. Return *false*.
- AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+ AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
- 1. Return the result of ComputedPropertyContains for |PropertyName| with argument _symbol_.
+ 1. Return the result of ComputedPropertyContains for |ClassElementName| with argument _symbol_.
+
+
+ FieldDefinition : ClassElementName Initializer?
+
+
+ 1. Return the result of ComputedPropertyContains for |ClassElementName| with argument _symbol_.
@@ -7885,14 +8260,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 :
@@ -7900,7 +8275,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 :
@@ -7908,7 +8283,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 :
@@ -7916,7 +8291,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_.
@@ -8180,6 +8555,7 @@ Static Semantics: AssignmentTargetType
MemberExpression `[` Expression `]`
MemberExpression `.` IdentifierName
SuperProperty
+ MemberExpression `.` PrivateIdentifier
1. Return ~simple~.
@@ -8346,30 +8722,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~.
@@ -9392,7 +9780,7 @@ GetIdentifierReference ( _env_, _name_, _strict_ )
NewDeclarativeEnvironment ( _E_ )
- The abstract operation NewDeclarativeEnvironment takes argument _E_ (an Environment Record). It performs the following steps when called:
+ The abstract operation NewDeclarativeEnvironment takes argument _E_ (an Environment Record or *null*). It performs the following steps when called:
1. Let _env_ be a new declarative Environment Record containing no bindings.
1. Set _env_.[[OuterEnv]] to _E_.
@@ -9668,11 +10056,20 @@ Execution Contexts
Identifies the Environment Record that holds bindings created by |VariableStatement|s within this execution context.
+
+
+ PrivateEnvironment
+ |
+
+ Identifies the Environment Record that holds Private Names created by |ClassElement|s.
+ |
+
The LexicalEnvironment and VariableEnvironment components of an execution context are always Environment Records.
Execution contexts representing the evaluation of generator objects have the additional state components listed in .
+ The PrivateEnvironment Lexical Context is always a chain of Declaration Contexts. Each name begins with *"#"*.
@@ -10668,6 +11065,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]]
+ |
+
+ Environment Record
+ |
+
+ The Environment Record for Private Names that the function was closed over. Used as the outer environment for Private Names when evaluating the code of the function.
+ |
+
[[FormalParameters]]
@@ -10767,6 +11175,17 @@ ECMAScript Function Objects
The source text that defines the function.
|
+
+
+ [[Fields]]
+ |
+
+ List of ClassFieldDefinition Records
+ |
+
+ If the function is a class with instance field declarations, this is a list of records representing those fields and their initializers.
+ |
+
[[IsClassConstructor]]
@@ -10778,6 +11197,28 @@ ECMAScript Function Objects
Indicates whether the function is a class constructor. (If *true*, invoking the function's [[Call]] will immediately throw a *TypeError* exception.)
|
+
+
+ [[ClassFieldInitializer]]
+ |
+
+ Boolean
+ |
+
+ *true* if this is a class field initializer, *false* otherwise.
+ |
+
+
+
+ [[PrivateBrand]]
+ |
+
+ Object | *undefined*
+ |
+
+ TODO
+ |
+
@@ -10817,6 +11258,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_.
@@ -10880,6 +11322,17 @@ Runtime Semantics: EvaluateBody
1. Return ? EvaluateAsyncConciseBody of |AsyncConciseBody| with arguments _functionObject_ and _argumentsList_.
+
+ Initializer :
+ `=` AssignmentExpression
+
+
+ 1. Assert: _argumentsList_ is empty.
+ 1. Let _exprRef_ be the result of evaluating |AssignmentExpression|.
+ 1. Let _exprValue_ be ? GetValue(_exprRef_).
+ 1. Return Completion { [[Type]]: ~return~, [[Value]]: _exprValue_, [[Target]]: ~empty~ }.
+
+ FunctionDeclarationInstantiation would not have any observable behaviour here, so its call is omitted.
@@ -10903,7 +11356,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 _result_ be InitializeInstanceElements(_thisArgument_, _F_).
+ 1. If _result_ is an abrupt completion, then
+ 1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context.
+ 1. Return Completion(_result_).
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.
@@ -10917,8 +11375,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_ (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:
1. Assert: Type(_functionPrototype_) is Object.
1. Let _internalSlotsList_ be the internal slots listed in .
@@ -10934,9 +11392,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_.[[ClassFieldInitializer]] to *false*.
1. Let _len_ be the ExpectedArgumentCount of _ParameterList_.
1. Perform ! SetFunctionLength(_F_, _len_).
1. Return _F_.
@@ -11005,17 +11465,34 @@ MakeMethod ( _F_, _homeObject_ )
+
+ DefineMethodProperty ( _key_, _homeObject_, _closure_, _enumerable_ )
+
+ 1. Perform SetFunctionName(_closure_, _key_).
+ 1. If _key_ is a Private Name, then
+ 1. Assert: _key_ does not have a [[Kind]] field.
+ 1. Set _key_.[[Kind]] to ~method~.
+ 1. Set _key_.[[Value]] to _closure_.
+ 1. Set _key_.[[Brand]] to _homeObject_.
+ 1. Else,
+ 1. Let _desc_ be the PropertyDescriptor { [[Value]]: _closure_, [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true* }.
+ 1. Perform ? DefinePropertyOrThrow(_homeObject_, _key_, _desc_).
+
+
+
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: Type(_name_) is either Symbol, String, or Private Name.
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
@@ -11149,9 +11626,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~).
@@ -13342,6 +13820,7 @@ Syntax
CommonToken ::
IdentifierName
+ PrivateIdentifier
Punctuator
NumericLiteral
StringLiteral
@@ -13362,6 +13841,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
@@ -14749,6 +15231,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|.
+
@@ -15056,6 +15545,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
@@ -15175,25 +15667,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_.
@@ -15548,6 +16040,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] `]`
@@ -15575,6 +16068,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]
@@ -15725,6 +16219,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|.
@@ -15739,6 +16241,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_).
+
@@ -15888,7 +16398,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_.
@@ -16311,7 +16825,7 @@ Static Semantics: Early Errors
UnaryExpression : `delete` UnaryExpression
ClassElement : MethodDefinition
@@ -20543,6 +21103,32 @@ Static Semantics: Early Errors
It is a Syntax Error if PropName of |MethodDefinition| is *"prototype"*.
+
+ ClassElement : FieldDefinition `;`
+
+ - It is a Syntax Error if PropName of |FieldDefinition| is *"constructor"*.
+
+
+ ClassElement : `static` FieldDefinition `;`
+
+ -
+ It is a Syntax Error if PropName of |FieldDefinition| is *"prototype"* or *"constructor"*.
+
+
+
+
+ FieldDefinition :
+ ClassElementName Initializer?
+
+
+ - It is a Syntax Error if ContainsArguments of |Initializer| is *true*.
+ - It is a Syntax Error if |Initializer| is present and |Initializer| Contains |SuperCall| is *true*.
+
+
+ ClassElementName : PrivateIdentifier
+
+ - It is a Syntax Error if StringValue of |PrivateIdentifier| is *"#constructor"*.
+
@@ -20591,6 +21177,14 @@ Static Semantics: IsStatic
1. Return *true*.
+ ClassElement : FieldDefinition `;`
+
+ 1. Return *false*.
+
+ ClassElement : `static` FieldDefinition `;`
+
+ 1. Return *true*.
+
ClassElement : `;`
1. Return *false*.
@@ -20632,6 +21226,218 @@ Static Semantics: PrototypePropertyNameList
+
+ Static Semantics: AllPrivateIdentifiersValid
+ With parameter _names_.
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. If StringValue of |PrivateIdentifier| is in _names_, return *true*.
+ 1. Return *false*.
+
+
+ CallExpression : CallExpression `.` PrivateIdentifier
+
+ 1. If StringValue of |PrivateIdentifier| is in _names_, return *true*.
+ 1. Return *false*.
+
+
+ ClassBody : ClassElementList
+
+ 1. Let _newNames_ be a copy of _names_.
+ 1. Append to _newNames_ the elements of PrivateBoundIdentifiers of |ClassBody|.
+ 1. Return AllPrivateIdentifiersValid of |ClassElementList| with argument _newNames_.
+
+
+ For all other grammatical productions, recurse on subexpressions/substatements, passing in the _names_ of the caller. If all pieces return *true*, then return *true*. If any returns *false*, return *false*.
+
+
+
+ Static Semantics: PrivateBoundIdentifiers
+
+ FieldDefinition : ClassElementName Initializer?
+
+
+ 1. Return PrivateBoundIdentifiers of |ClassElementName|.
+
+
+
+ ClassElementName : PrivateIdentifier
+
+
+ 1. Return a List whose sole element is the StringValue of |PrivateIdentifier|.
+
+
+
+ ClassElementName : PropertyName
+
+ ClassElement : `;`
+
+
+ 1. Return a new empty List.
+
+
+
+ ClassElementList : ClassElementList ClassElement
+
+
+ 1. Let _names_ be PrivateBoundIdentifiers of |ClassElementList|.
+ 1. Append to _names_ the elements of PrivateBoundIdentifiers of |ClassElement|.
+ 1. Return _names_.
+
+
+
+ MethodDefinition :
+ ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}`
+ `get` ClassElementName `(` `)` `{` FunctionBody `}`
+ `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}`
+
+ GeneratorMethod :
+ `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}`
+
+ AsyncMethod :
+ `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncGeneratorMethod :
+ `async` `*` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncGeneratorBody `}`
+
+
+ 1. Return PrivateBoundIdentifiers of |ClassElementName|.
+
+
+
+
+ Static Semantics: ContainsArguments
+
+ IdentifierReference : Identifier
+
+
+ 1. If the StringValue of |Identifier| is *"arguments"*, return *true*.
+ 1. Else, return *false*.
+
+
+
+ FunctionDeclaration : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}`
+
+ FunctionDeclaration : `function` `(` FormalParameters `)` `{` FunctionBody `}`
+
+ FunctionExpression : `function` BindingIdentifier? `(` FormalParameters `)` `{` FunctionBody `}`
+
+
+ 1. Return *false*.
+
+
+
+ MethodDefinition :
+ ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}`
+ `get` ClassElementName `(` `)` `{` FunctionBody `}`
+ `set` ClassElementName `(` PropertySetParameterList `)` `{` FunctionBody `}`
+
+
+ 1. Return the result of ContainsArguments of |ClassElementName|.
+
+
+
+ GeneratorMethod : `*` ClassElementName `(` UniqueFormalParameters `)` `{` GeneratorBody `}`
+
+
+ 1. Return the result of ContainsArguments of |ClassElementName|.
+
+
+
+ GeneratorDeclaration : `function` `*` BindingIdentifier `(` FormalParameters `)` `{` GeneratorBody `}`
+
+ GeneratorDeclaration : `function` `*` `(` FormalParameters `)` `{` GeneratorBody `}`
+
+ GeneratorExpression : `function` `*` BindingIdentifier? `(` FormalParameters `)` `{` GeneratorBody `}`
+
+
+ 1. Return *false*.
+
+
+ ClassBody : ClassElementList
+
+ 1. Return *false*.
+
+
+
+ AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+
+
+ 1. Return the result of ContainsArguments of |ClassElementName|.
+
+
+
+ AsyncFunctionDeclaration : `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncFunctionDeclaration : `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncFunctionExpression : `async` `function` `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+ AsyncFunctionExpression : `async` `function` BindingIdentifier `(` FormalParameters `)` `{` AsyncFunctionBody `}`
+
+
+ 1. Return *false*.
+
+
+ For all other grammatical productions, recurse on all nonterminals. If any piece returns *true*, then return *true*. Otherwise return *false*.
+
+
+
+ Runtime Semantics: ClassFieldDefinitionEvaluation
+
+ With parameter _homeObject_.
+
+
+ FieldDefinition : ClassElementName Initializer?
+
+
+ 1. Let _name_ be the result of evaluating |ClassElementName|.
+ 1. ReturnIfAbrupt(_name_).
+ 1. If |Initializer_opt| is present, then
+ 1. Let _lex_ be the LexicalEnvironment of the running execution context.
+ 1. Let _formalParameterList_ be an instance of the production FormalParameters : [empty].
+ 1. Let _privateScope_ be the running execution context's PrivateEnvironment.
+ 1. Let _initializer_ be ! OrdinaryFunctionCreate(~Method~, _formalParameterList_, |Initializer|, _lex_, _privateScope_).
+ 1. Perform MakeMethod(_initializer_, _homeObject_).
+ 1. Set _initializer_.[[ClassFieldInitializer]] to *true*.
+ 1. Let _isAnonymousFunctionDefinition_ be IsAnonymousFunctionDefinition(|Initializer|).
+ 1. Else,
+ 1. Let _initializer_ be ~empty~.
+ 1. Let _isAnonymousFunctionDefinition_ be *false*.
+ 1. Return the ClassFieldDefinition Record { [[Name]]: _name_, [[Initializer]]: _initializer_, [[IsAnonymousFunctionDefinition]]: _isAnonymousFunctionDefinition_ }.
+
+
+
+
+ Runtime Semantics: ClassElementEvaluation
+ With parameters _object_ and _enumerable_.
+
+
+ ClassElement : FieldDefinition `;`
+
+ ClassElement : `static` FieldDefinition `;`
+
+
+ 1. Return ClassFieldDefinitionEvaluation of |FieldDefinition| with argument _object_.
+
+
+
+ ClassElement : MethodDefinition
+
+ ClassElement : `static` MethodDefinition
+
+
+ 1. Return PropertyDefinitionEvaluation of |MethodDefinition| with arguments _object_ and _enumerable_.
+
+
+
+ ClassElement : `;`
+
+
+ 1. Return.
+
+
+
Runtime Semantics: ClassDefinitionEvaluation
With parameters _classBinding_ and _className_.
@@ -20641,11 +21447,17 @@ Runtime Semantics: ClassDefinitionEvaluation
1. Let _classScope_ be NewDeclarativeEnvironment(_env_).
1. If _classBinding_ is not *undefined*, then
1. Perform _classScope_.CreateImmutableBinding(_classBinding_, *true*).
+ 1. Let _outerPrivateEnvironment_ be the running execution context's PrivateEnvironment.
+ 1. Let _classPrivateEnvironment_ be NewDeclarativeEnvironment(_outerPrivateEnvironment_).
+ 1. If |ClassBody_opt| is present, then
+ 1. For each element _dn_ of the PrivateBoundIdentifiers of |ClassBody_opt|, do
+ 1. Perform _classPrivateEnvironment_.CreateImmutableBinding(_dn_, *true*).
1. If |ClassHeritage_opt| is not present, then
1. Let _protoParent_ be %Object.prototype%.
1. Let _constructorParent_ be %Function.prototype%.
1. Else,
1. Set the running execution context's LexicalEnvironment to _classScope_.
+ 1. NOTE: The running execution context's PrivateEnvironment is _outerPrivateEnvironment_ when evaluating |ClassHeritage|.
1. Let _superclassRef_ be the result of evaluating |ClassHeritage|.
1. Set the running execution context's LexicalEnvironment to _env_.
1. Let _superclass_ be ? GetValue(_superclassRef_).
@@ -20670,6 +21482,7 @@ Runtime Semantics: ClassDefinitionEvaluation
1. Set _constructor_ to ParseText(_constructorText_, |MethodDefinition[~Yield, ~Await]|).
1. Assert: _constructor_ is a Parse Node.
1. Set the running execution context's LexicalEnvironment to _classScope_.
+ 1. Set the running execution context's PrivateEnvironment to _classPrivateEnvironment_.
1. Let _constructorInfo_ be ! DefineMethod of _constructor_ with arguments _proto_ and _constructorParent_.
1. Let _F_ be _constructorInfo_.[[Closure]].
1. Perform SetFunctionName(_F_, _className_).
@@ -20677,19 +21490,39 @@ Runtime Semantics: ClassDefinitionEvaluation
1. If |ClassHeritage_opt| is present, set _F_.[[ConstructorKind]] to ~derived~.
1. Perform MakeClassConstructor(_F_).
1. Perform CreateMethodProperty(_proto_, *"constructor"*, _F_).
- 1. If |ClassBody_opt| is not present, let _methods_ be a new empty List.
- 1. Else, let _methods_ be NonConstructorMethodDefinitions of |ClassBody|.
- 1. For each |ClassElement| _m_ of _methods_, do
- 1. If IsStatic of _m_ is *false*, then
- 1. Let _status_ be PropertyDefinitionEvaluation of _m_ with arguments _proto_ and *false*.
+ 1. If |ClassBody_opt| is not present, let _elements_ be a new empty List.
+ 1. Else, let _elements_ be NonConstructorMethodDefinitions of |ClassBody|.
+ 1. Let _instanceFields_ be a new empty List.
+ 1. Let _staticFields_ be a new empty List.
+ 1. For each |ClassElement| _e_ of _elements_, do
+ 1. If IsStatic of _e_ is *false*, then
+ 1. Let _field_ be ClassElementEvaluation of _e_ with arguments _proto_ and *false*.
1. Else,
- 1. Let _status_ be PropertyDefinitionEvaluation of _m_ with arguments _F_ and *false*.
- 1. If _status_ is an abrupt completion, then
+ 1. Let _field_ be ClassElementEvaluation of _e_ with arguments _F_ and *false*.
+ 1. If _field_ is an abrupt completion, then
1. Set the running execution context's LexicalEnvironment to _env_.
- 1. Return Completion(_status_).
+ 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
+ 1. Return Completion(_field_).
+ 1. If _field_ is a ClassFieldDefinition Record, then
+ 1. If IsStatic of _e_ is *false*, append _field_ to _instanceFields_.
+ 1. Else, append _field_ to _staticFields_.
1. Set the running execution context's LexicalEnvironment to _env_.
1. If _classBinding_ is not *undefined*, then
1. Perform _classScope_.InitializeBinding(_classBinding_, _F_).
+ 1. Set _F_.[[Fields]] to _instanceFields_.
+ 1. If PrivateBoundIdentifiers of |ClassBody| contains a Private Name _P_ such that _P_.[[Kind]] is either ~method~ or ~accessor~ and _P_.[[Brand]] is _proto_, then
+ 1. Set _F_.[[PrivateBrand]] to _proto_.
+ 1. If PrivateBoundIdentifiers of |ClassBody| contains a Private Name _P_ such that _P_.[[Kind]] is either ~method~ or ~accessor~ and _P_.[[Brand]] is _F_, then
+ 1. Let _result_ be PrivateBrandAdd(_F_, _F_).
+ 1. If _result_ is an abrupt completion, then
+ 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
+ 1. Return _result_.
+ 1. For each element _fieldRecord_ of _staticFields_, do
+ 1. Let _result_ be DefineField(_F_, _fieldRecord_).
+ 1. If _result_ is an abrupt completion, then
+ 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
+ 1. Return _result_.
+ 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
1. Return _F_.
@@ -20739,6 +21572,25 @@ Runtime Semantics: Evaluation
1. Set _value_.[[SourceText]] to the source text matched by |ClassExpression|.
1. Return _value_.
+ ClassElementName : PropertyName
+
+ 1. Return the result of evaluating |PropertyName|.
+
+ ClassElementName : PrivateIdentifier
+
+ 1. Let _privateIdentifier_ be StringValue of |PrivateIdentifier|.
+ 1. Let _privateEnvRec_ be the running execution context's PrivateEnvironment.
+ 1. Assert: _privateEnvRec_ has a binding for _privateIdentifier_.
+ 1. If the binding for _privateIdentifier_ in _privateEnvRec_ is an uninitialized binding, then
+ 1. Let _privateName_ be NewPrivateName(_privateIdentifier_).
+ 1. Perform ! _privateEnvRec_.InitializeBinding(_privateIdentifier_, _privateName_).
+ 1. Else,
+ 1. Let _privateName_ be ! _privateEnvRec_.GetBindingValue(_privateIdentifier_, *true*).
+ 1. NOTE: The only case where this may occur is in getter/setter pairs; other duplicates are prohibited as a Syntax Error.
+ 1. Assert: _privateName_ is a Private Name.
+ 1. Assert: _privateName_.[[Description]] is _privateIdentifier_.
+ 1. Return _privateName_.
+
@@ -20755,7 +21607,7 @@ Syntax
`async` [no LineTerminator here] `function` BindingIdentifier[~Yield, +Await] `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
AsyncMethod[Yield, Await] :
- `async` [no LineTerminator here] PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ `async` [no LineTerminator here] ClassElementName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
AsyncFunctionBody :
FunctionBody[~Yield, +Await]
@@ -20784,7 +21636,7 @@ Syntax
Static Semantics: Early Errors
- AsyncMethod : `async` PropertyName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
+ AsyncMethod : `async` ClassElementName `(` UniqueFormalParameters `)` `{` AsyncFunctionBody `}`
@@ -21567,6 +22428,8 @@ ScriptEvaluation ( _scriptRecord_ )
1. Set the ScriptOrModule of _scriptContext_ to _scriptRecord_.
1. Set the VariableEnvironment of _scriptContext_ to _globalEnv_.
1. Set the LexicalEnvironment of _scriptContext_ to _globalEnv_.
+ 1. Let _privateEnv_ be NewDeclarativeEnvironment(*null*).
+ 1. Set the PrivateEnvironment of _scriptContext_ to _privateEnv_.
1. Suspend the currently running execution context.
1. Push _scriptContext_ onto the execution context stack; _scriptContext_ is now the running execution context.
1. Let _scriptBody_ be _scriptRecord_.[[ECMAScriptCode]].
@@ -21629,6 +22492,7 @@ GlobalDeclarationInstantiation ( _script_, _env_ )
1. NOTE: No abnormal terminations occur after this algorithm step if the global object is an ordinary object. However, if the global object is a Proxy exotic object it may exhibit behaviours that cause abnormal terminations in some of the following steps.
1. [id="step-globaldeclarationinstantiation-web-compat-insertion-point"] NOTE: Annex adds additional steps at this point.
1. Let _lexDeclarations_ be the LexicallyScopedDeclarations of _script_.
+ 1. Let _privateEnv_ be NewDeclarativeEnvironment(*null*).
1. For each element _d_ of _lexDeclarations_, do
1. NOTE: Lexically declared names are only instantiated here but not initialized.
1. For each element _dn_ of the BoundNames of _d_, do
@@ -21638,7 +22502,7 @@ GlobalDeclarationInstantiation ( _script_, _env_ )
1. Perform ? _env_.CreateMutableBinding(_dn_, *false*).
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 _env_.
+ 1. Let _fo_ be InstantiateFunctionObject of _f_ with arguments _env_ and _privateEnv_.
1. Perform ? _env_.CreateGlobalFunctionBinding(_fn_, _fo_, *false*).
1. For each String _vn_ of _declaredVarNames_, do
1. Perform ? _env_.CreateGlobalVarBinding(_vn_, *false*).
@@ -21705,6 +22569,9 @@ Static Semantics: Early Errors
It is a Syntax Error if ContainsUndefinedContinueTarget of |ModuleItemList| with arguments « » and « » is *true*.
+
+ It is a Syntax Error if AllPrivateIdentifiersValid of |ModuleItemList| with argument « » is *false*.
+
The duplicate ExportedNames rule implies that multiple `export default` |ExportDeclaration| items within a |ModuleBody| is a Syntax Error. Additional error conditions relating to conflicting or duplicate declarations are checked during module linking prior to evaluation of a |Module|. If any such errors are detected the |Module| is not evaluated.
@@ -22831,6 +23698,7 @@ InitializeEnvironment ( ) Concrete Method
1. Call _env_.InitializeBinding(_dn_, *undefined*).
1. Append _dn_ to _declaredVarNames_.
1. Let _lexDeclarations_ be the LexicallyScopedDeclarations of _code_.
+ 1. Let _privateEnv_ be NewDeclarativeEnvironment(*null*).
1. For each element _d_ of _lexDeclarations_, do
1. For each element _dn_ of the BoundNames of _d_, do
1. If IsConstantDeclaration of _d_ is *true*, then
@@ -22838,7 +23706,7 @@ InitializeEnvironment ( ) Concrete Method
1. Else,
1. Perform ! _env_.CreateMutableBinding(_dn_, *false*).
1. If _d_ is a |FunctionDeclaration|, a |GeneratorDeclaration|, an |AsyncFunctionDeclaration|, or an |AsyncGeneratorDeclaration|, then
- 1. Let _fo_ be InstantiateFunctionObject of _d_ with argument _env_.
+ 1. Let _fo_ be InstantiateFunctionObject of _d_ with arguments _env_ and _privateEnv_.
1. Call _env_.InitializeBinding(_dn_, _fo_).
1. Remove _moduleContext_ from the execution context stack.
1. Return NormalCompletion(~empty~).
@@ -23652,6 +24520,7 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. Let _inFunction_ be *false*.
1. Let _inMethod_ be *false*.
1. Let _inDerivedConstructor_ be *false*.
+ 1. Let _inClassFieldInitializer_ be *false*.
1. If _direct_ is *true*, then
1. Let _thisEnvRec_ be ! GetThisEnvironment().
1. If _thisEnvRec_ is a function Environment Record, then
@@ -23659,6 +24528,7 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. Set _inFunction_ to *true*.
1. Set _inMethod_ to _thisEnvRec_.HasSuperBinding().
1. If _F_.[[ConstructorKind]] is ~derived~, set _inDerivedConstructor_ to *true*.
+ 1. Set _inClassFieldInitializer_ to _F_.[[ClassFieldInitializer]].
1. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
1. Let _script_ be ParseText(! StringToCodePoints(_x_), |Script|).
1. If _script_ is a List of errors, throw a *SyntaxError* exception.
@@ -23667,6 +24537,7 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. If _inFunction_ is *false*, and _body_ Contains |NewTarget|, throw a *SyntaxError* exception.
1. If _inMethod_ is *false*, and _body_ Contains |SuperProperty|, throw a *SyntaxError* exception.
1. If _inDerivedConstructor_ is *false*, and _body_ Contains |SuperCall|, throw a *SyntaxError* exception.
+ 1. If _inClassFieldInitializer_ is *true*, and ContainsArguments of _body_ is *true*, throw a *SyntaxError* exception.
1. If _strictCaller_ is *true*, let _strictEval_ be *true*.
1. Else, let _strictEval_ be IsStrict of _script_.
1. Let _runningContext_ be the running execution context.
@@ -23674,9 +24545,11 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. If _direct_ is *true*, then
1. Let _lexEnv_ be NewDeclarativeEnvironment(_runningContext_'s LexicalEnvironment).
1. Let _varEnv_ be _runningContext_'s VariableEnvironment.
+ 1. Let _privateEnv_ be _runningContext_'s PrivateEnvironment.
1. Else,
1. Let _lexEnv_ be NewDeclarativeEnvironment(_evalRealm_.[[GlobalEnv]]).
1. Let _varEnv_ be _evalRealm_.[[GlobalEnv]].
+ 1. Let _privateEnv_ be NewDeclarativeEnvironment(*null*).
1. If _strictEval_ is *true*, set _varEnv_ to _lexEnv_.
1. If _runningContext_ is not already suspended, suspend _runningContext_.
1. Let _evalContext_ be a new ECMAScript code execution context.
@@ -23685,8 +24558,9 @@ PerformEval ( _x_, _callerRealm_, _strictCaller_, _direct_ )
1. Set _evalContext_'s ScriptOrModule to _runningContext_'s ScriptOrModule.
1. Set _evalContext_'s VariableEnvironment to _varEnv_.
1. Set _evalContext_'s LexicalEnvironment to _lexEnv_.
+ 1. Set _evalContext_'s PrivateEnvironment to _privateEnv_.
1. Push _evalContext_ onto the execution context stack; _evalContext_ is now the running execution context.
- 1. Let _result_ be EvalDeclarationInstantiation(_body_, _varEnv_, _lexEnv_, _strictEval_).
+ 1. Let _result_ be EvalDeclarationInstantiation(_body_, _varEnv_, _lexEnv_, _privateEnv_, _strictEval_).
1. If _result_.[[Type]] is ~normal~, then
1. Set _result_ to the result of evaluating _body_.
1. If _result_.[[Type]] is ~normal~ and _result_.[[Value]] is ~empty~, then
@@ -23707,8 +24581,8 @@ HostEnsureCanCompileStrings ( _callerRealm_, _calleeRealm_ )
- EvalDeclarationInstantiation ( _body_, _varEnv_, _lexEnv_, _strict_ )
- The abstract operation EvalDeclarationInstantiation takes arguments _body_, _varEnv_, _lexEnv_, and _strict_. It performs the following steps when called:
+ EvalDeclarationInstantiation ( _body_, _varEnv_, _lexEnv_, _privateEnv_, _strict_ )
+ The abstract operation EvalDeclarationInstantiation takes arguments _body_, _varEnv_, _lexEnv_, _privateEnv_, and _strict_. It performs the following steps when called: