Environment Record is a specification type used to define the association of Identifiers to specific variables and functions, based upon the lexical nesting structure of ECMAScript code. Usually an Environment Record is associated with some specific syntactic structure of ECMAScript code such as a FunctionDeclaration, a BlockStatement, or a Catch clause of a TryStatement. Each time such code is evaluated, a new Environment Record is created to record the identifier bindings that are created by that code.
Every Environment Record has an [[OuterEnv]] field, which is either null or a reference to an outer Environment Record. This is used to model the logical nesting of Environment Record values. The outer reference of an (inner) Environment Record is a reference to the Environment Record that logically surrounds the inner Environment Record. An outer Environment Record may, of course, have its own outer Environment Record. An Environment Record may serve as the outer environment for multiple inner Environment Records. For example, if a FunctionDeclaration contains two nested FunctionDeclarations then the Environment Records of each of the nested functions will have as their outer Environment Record the Environment Record of the current evaluation of the surrounding function.
Environment Records are purely specification mechanisms and need not correspond to any specific artefact of an ECMAScript implementation. It is impossible for an ECMAScript program to directly access or manipulate such values.
A Function Environment Record corresponds to the invocation of an ECMAScript function object, and contains bindings for the top-level declarations within that function. It may establish a new this binding. It also captures the state necessary to support super method invocations.
An Object Environment Record is used to define the effect of ECMAScript elements such as WithStatement that associate identifier bindings with the properties of some object.
A Global Environment Record is used for Script global declarations. It does not have an outer environment; its [[OuterEnv]] is null. It may be prepopulated with identifier bindings and it includes an associated global object whose properties provide some of the global environment's identifier bindings. As ECMAScript code is executed, additional properties may be added to the global object and the initial properties may be modified.
The Environment Record abstract class includes the abstract specification methods defined in Table 16. These abstract methods have distinct concrete algorithms for each of the concrete subclasses.
Determine if an Environment Record has a binding for the String value N. Return true if it does and false if it does not.
CreateMutableBinding(N, D)
Create a new but uninitialized mutable binding in an Environment Record. The String value N is the text of the bound name. If the Boolean argument D is true the binding may be subsequently deleted.
CreateImmutableBinding(N, S)
Create a new but uninitialized immutable binding in an Environment Record. The String value N is the text of the bound name. If S is true then attempts to set it after it has been initialized will always throw an exception, regardless of the strict mode setting of operations that reference that binding.
InitializeBinding(N, V)
Set the value of an already existing but uninitialized binding in an Environment Record. The String value N is the text of the bound name. V is the value for the binding and is a value of any ECMAScript language type.
SetMutableBinding(N, V, S)
Set the value of an already existing mutable binding in an Environment Record. The String value N is the text of the bound name. V is the value for the binding and may be a value of any ECMAScript language type. Sis a Boolean flag. If S is true and the binding cannot be set throw a TypeError exception.
GetBindingValue(N, S)
Returns the value of an already existing binding from an Environment Record. The String value N is the text of the bound name. S is used to identify references originating in strict mode code or that otherwise require strict mode reference semantics. If S is true and the binding does not exist throw a ReferenceError exception. If the binding exists but is uninitialized a ReferenceError is thrown, regardless of the value of S.
DeleteBinding(N)
Delete a binding from an Environment Record. The String value N is the text of the bound name. If a binding for N exists, remove the binding and return true. If the binding exists but cannot be removed return false. If the binding does not exist return true.
HasThisBinding()
Determine if an Environment Record establishes a this binding. Return true if it does and false if it does not.
HasSuperBinding()
Determine if an Environment Record establishes a super method binding. Return true if it does and false if it does not.
WithBaseObject()
If this Environment Record is associated with a with statement, return the with object. Otherwise, return undefined.
9.1.1.1 Declarative Environment Records
Each Declarative Environment Record is associated with an ECMAScript program scope containing variable, constant, let, class, module, import, and/or function declarations. A Declarative Environment Record binds the set of identifiers defined by the declarations contained within its scope.
The behaviour of the concrete specification methods for Declarative Environment Records is defined by the following algorithms.
9.1.1.1.1 HasBinding ( N )
The HasBinding concrete method of a Declarative Environment RecordenvRec takes argument N (a String) and returns a normal completion containing a Boolean. It determines if the argument identifier is one of the identifiers bound by the record. It performs the following steps when called:
If envRec has a binding for N, return true.
Return false.
9.1.1.1.2 CreateMutableBinding ( N, D )
The CreateMutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and D (a Boolean) and returns a normal completion containingunused. It creates a new mutable binding for the name N that is uninitialized. A binding must not already exist in this Environment Record for N. If D is true, the new binding is marked as being subject to deletion. It performs the following steps when called:
Assert: envRec does not already have a binding for N.
Create a mutable binding in envRec for N and record that it is uninitialized. If D is true, record that the newly created binding may be deleted by a subsequent DeleteBinding call.
Return unused.
9.1.1.1.3 CreateImmutableBinding ( N, S )
The CreateImmutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns a normal completion containingunused. It creates a new immutable binding for the name N that is uninitialized. A binding must not already exist in this Environment Record for N. If S is true, the new binding is marked as a strict binding. It performs the following steps when called:
Assert: envRec does not already have a binding for N.
Create an immutable binding in envRec for N and record that it is uninitialized. If S is true, record that the newly created binding is a strict binding.
Return unused.
9.1.1.1.4 InitializeBinding ( N, V )
The InitializeBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and V (an ECMAScript language value) and returns a normal completion containingunused. It is used to set the bound value of the current binding of the identifier whose name is N to the value V. An uninitialized binding for N must already exist. It performs the following steps when called:
Assert: envRec must have an uninitialized binding for N.
Set the bound value for N in envRec to V.
Record that the binding for N in envRec has been initialized.
Return unused.
9.1.1.1.5 SetMutableBinding ( N, V, S )
The SetMutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containingunused or a throw completion. It attempts to change the bound value of the current binding of the identifier whose name is N to the value V. A binding for N normally already exists, but in rare cases it may not. If the binding is an immutable binding, a TypeError is thrown if S is true. It performs the following steps when called:
If envRec does not have a binding for N, then
If S is true, throw a ReferenceError exception.
Perform ! envRec.CreateMutableBinding(N, true).
Perform ! envRec.InitializeBinding(N, V).
Return unused.
If the binding for N in envRec is a strict binding, set S to true.
If the binding for N in envRec has not yet been initialized, throw a ReferenceError exception.
Else if the binding for N in envRec is a mutable binding, change its bound value to V.
Else,
Assert: This is an attempt to change the value of an immutable binding.
If S is true, throw a TypeError exception.
Return unused.
Note
An example of ECMAScript code that results in a missing binding at step 1 is:
functionf() { eval("var x; x = (delete x, 0);"); }
9.1.1.1.6 GetBindingValue ( N, S )
The GetBindingValue concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns the value of its bound identifier whose name is N. If the binding exists but is uninitialized a ReferenceError is thrown, regardless of the value of S. It performs the following steps when called:
If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
Return the value currently bound to N in envRec.
9.1.1.1.7 DeleteBinding ( N )
The DeleteBinding concrete method of a Declarative Environment RecordenvRec takes argument N (a String) and returns a normal completion containing a Boolean. It can only delete bindings that have been explicitly designated as being subject to deletion. It performs the following steps when called:
If the binding for N in envRec cannot be deleted, return false.
Remove the binding for N from envRec.
Return true.
9.1.1.1.8 HasThisBinding ( )
The HasThisBinding concrete method of a Declarative Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The HasSuperBinding concrete method of a Declarative Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of a Declarative Environment RecordenvRec takes no arguments and returns undefined. It performs the following steps when called:
Return undefined.
9.1.1.2 Object Environment Records
Each Object Environment Record is associated with an object called its binding object. An Object Environment Record binds the set of string identifier names that directly correspond to the property names of its binding object. Property keys that are not strings in the form of an IdentifierName are not included in the set of bound identifiers. Both own and inherited properties are included in the set regardless of the setting of their [[Enumerable]] attribute. Because properties can be dynamically added and deleted from objects, the set of identifiers bound by an Object Environment Record may potentially change as a side-effect of any operation that adds or deletes properties. Any bindings that are created as a result of such a side-effect are considered to be a mutable binding even if the Writable attribute of the corresponding property is false. Immutable bindings do not exist for Object Environment Records.
Object Environment Records created for with statements (14.11) can provide their binding object as an implicit this value for use in function calls. The capability is controlled by a Boolean [[IsWithEnvironment]] field.
Object Environment Records have the additional state fields listed in Table 17.
Indicates whether this Environment Record is created for a with statement.
The behaviour of the concrete specification methods for Object Environment Records is defined by the following algorithms.
9.1.1.2.1 HasBinding ( N )
The HasBinding concrete method of an Object Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It determines if its associated binding object has a property whose name is N. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Let foundBinding be ? HasProperty(bindingObject, N).
If foundBinding is false, return false.
If envRec.[[IsWithEnvironment]] is false, return true.
The CreateMutableBinding concrete method of an Object Environment RecordenvRec takes arguments N (a String) and D (a Boolean) and returns either a normal completion containingunused or a throw completion. It creates in an Environment Record's associated binding object a property whose name is N and initializes it to the value undefined. If D is true, the new property's [[Configurable]] attribute is set to true; otherwise it is set to false. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Perform ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
Return unused.
Note
Normally envRec will not have a binding for N but if it does, the semantics of DefinePropertyOrThrow may result in an existing binding being replaced or shadowed or cause an abrupt completion to be returned.
9.1.1.2.3 CreateImmutableBinding ( N, S )
The CreateImmutableBinding concrete method of an Object Environment Record is never used within this specification.
In this specification, all uses of CreateMutableBinding for Object Environment Records are immediately followed by a call to InitializeBinding for the same name. Hence, this specification does not explicitly track the initialization state of bindings in Object Environment Records.
9.1.1.2.5 SetMutableBinding ( N, V, S )
The SetMutableBinding concrete method of an Object Environment RecordenvRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containingunused or a throw completion. It attempts to set the value of the Environment Record's associated binding object's property whose name is N to the value V. A property named N normally already exists but if it does not or is not currently writable, error handling is determined by S. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Let stillExists be ? HasProperty(bindingObject, N).
If stillExists is false and S is true, throw a ReferenceError exception.
The GetBindingValue concrete method of an Object Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns the value of its associated binding object's property whose name is N. The property should already exist but if it does not the result depends upon S. It performs the following steps when called:
The DeleteBinding concrete method of an Object Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It can only delete bindings that correspond to properties of the environment object whose [[Configurable]] attribute have the value true. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Return ? bindingObject.[[Delete]](N).
9.1.1.2.8 HasThisBinding ( )
The HasThisBinding concrete method of an Object Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The HasSuperBinding concrete method of an Object Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of an Object Environment RecordenvRec takes no arguments and returns an Object or undefined. It performs the following steps when called:
If envRec.[[IsWithEnvironment]] is true, return envRec.[[BindingObject]].
Otherwise, return undefined.
9.1.1.3 Function Environment Records
A Function Environment Record is a Declarative Environment Record that is used to represent the top-level scope of a function and, if the function is not an ArrowFunction, provides a this binding. If a function is not an ArrowFunction function and references super, its Function Environment Record also contains the state that is used to perform super method invocations from within the function.
Function Environment Records have the additional state fields listed in Table 18.
If this Environment Record was created by the [[Construct]] internal method, [[NewTarget]] is the value of the [[Construct]] newTarget parameter. Otherwise, its value is undefined.
Function Environment Records support all of the Declarative Environment Record methods listed in Table 16 and share the same specifications for all of those methods except for HasThisBinding and HasSuperBinding. In addition, Function Environment Records support the methods listed in Table 19:
Set the [[ThisValue]] and record that it has been initialized.
GetThisBinding()
Return the value of this Environment Record's this binding. Throws a ReferenceError if the this binding has not been initialized.
GetSuperBase()
Return the object that is the base for super property accesses bound in this Environment Record. The value undefined indicates that such accesses will produce runtime errors.
The behaviour of the additional concrete specification methods for Function Environment Records is defined by the following algorithms:
Assert: envRec.[[ThisBindingStatus]] is not lexical.
If envRec.[[ThisBindingStatus]] is initialized, throw a ReferenceError exception.
Set envRec.[[ThisValue]] to V.
Set envRec.[[ThisBindingStatus]] to initialized.
Return V.
9.1.1.3.2 HasThisBinding ( )
The HasThisBinding concrete method of a Function Environment RecordenvRec takes no arguments and returns a Boolean. It performs the following steps when called:
If envRec.[[ThisBindingStatus]] is lexical, return false; otherwise, return true.
9.1.1.3.3 HasSuperBinding ( )
The HasSuperBinding concrete method of a Function Environment RecordenvRec takes no arguments and returns a Boolean. It performs the following steps when called:
If envRec.[[ThisBindingStatus]] is lexical, return false.
If envRec.[[FunctionObject]].[[HomeObject]] is undefined, return false; otherwise, return true.
A Global Environment Record is used to represent the outer most scope that is shared by all of the ECMAScript Script elements that are processed in a common realm. A Global Environment Record provides the bindings for built-in globals (clause 19), properties of the global object, and for all top-level declarations (8.2.9, 8.2.11) that occur within a Script.
Determines if the argument is the name of a global object property that may not be shadowed by a global lexical binding.
CanDeclareGlobalVar (N)
Determines if a corresponding CreateGlobalVarBinding call would succeed if called for the same argument N.
CanDeclareGlobalFunction (N)
Determines if a corresponding CreateGlobalFunctionBinding call would succeed if called for the same argument N.
CreateGlobalVarBinding(N, D)
Used to create and initialize to undefined a global var binding in the [[ObjectRecord]] component of a Global Environment Record. The binding will be a mutable binding. The corresponding global object property will have attribute values appropriate for a var. The String value N is the bound name. If D is true, the binding may be deleted. Logically equivalent to CreateMutableBinding followed by a SetMutableBinding but it allows var declarations to receive special treatment.
CreateGlobalFunctionBinding(N, V, D)
Create and initialize a global function binding in the [[ObjectRecord]] component of a Global Environment Record. The binding will be a mutable binding. The corresponding global object property will have attribute values appropriate for a function. The String value N is the bound name. V is the initialization value. If the Boolean argument D is true, the binding may be deleted. Logically equivalent to CreateMutableBinding followed by a SetMutableBinding but it allows function declarations to receive special treatment.
The behaviour of the concrete specification methods for Global Environment Records is defined by the following algorithms.
9.1.1.4.1 HasBinding ( N )
The HasBinding concrete method of a Global Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It determines if the argument identifier is one of the identifiers bound by the record. It performs the following steps when called:
Let DclRec be envRec.[[DeclarativeRecord]].
If ! DclRec.HasBinding(N) is true, return true.
Let ObjRec be envRec.[[ObjectRecord]].
Return ? ObjRec.HasBinding(N).
9.1.1.4.2 CreateMutableBinding ( N, D )
The CreateMutableBinding concrete method of a Global Environment RecordenvRec takes arguments N (a String) and D (a Boolean) and returns either a normal completion containingunused or a throw completion. It creates a new mutable binding for the name N that is uninitialized. The binding is created in the associated DeclarativeRecord. A binding for N must not already exist in the DeclarativeRecord. If D is true, the new binding is marked as being subject to deletion. It performs the following steps when called:
Let DclRec be envRec.[[DeclarativeRecord]].
If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
Return ! DclRec.CreateMutableBinding(N, D).
9.1.1.4.3 CreateImmutableBinding ( N, S )
The CreateImmutableBinding concrete method of a Global Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containingunused or a throw completion. It creates a new immutable binding for the name N that is uninitialized. A binding must not already exist in this Environment Record for N. If S is true, the new binding is marked as a strict binding. It performs the following steps when called:
Let DclRec be envRec.[[DeclarativeRecord]].
If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
Return ! DclRec.CreateImmutableBinding(N, S).
9.1.1.4.4 InitializeBinding ( N, V )
The InitializeBinding concrete method of a Global Environment RecordenvRec takes arguments N (a String) and V (an ECMAScript language value) and returns either a normal completion containingunused or a throw completion. It is used to set the bound value of the current binding of the identifier whose name is N to the value V. An uninitialized binding for N must already exist. It performs the following steps when called:
The SetMutableBinding concrete method of a Global Environment RecordenvRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containingunused or a throw completion. It attempts to change the bound value of the current binding of the identifier whose name is N to the value V. If the binding is an immutable binding and S is true, a TypeError is thrown. A property named N normally already exists but if it does not or is not currently writable, error handling is determined by S. It performs the following steps when called:
Let DclRec be envRec.[[DeclarativeRecord]].
If ! DclRec.HasBinding(N) is true, then
Return ? DclRec.SetMutableBinding(N, V, S).
Let ObjRec be envRec.[[ObjectRecord]].
Return ? ObjRec.SetMutableBinding(N, V, S).
9.1.1.4.6 GetBindingValue ( N, S )
The GetBindingValue concrete method of a Global Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns the value of its bound identifier whose name is N. If the binding is an uninitialized binding throw a ReferenceError exception. A property named N normally already exists but if it does not or is not currently writable, error handling is determined by S. It performs the following steps when called:
Let DclRec be envRec.[[DeclarativeRecord]].
If ! DclRec.HasBinding(N) is true, then
Return ? DclRec.GetBindingValue(N, S).
Let ObjRec be envRec.[[ObjectRecord]].
Return ? ObjRec.GetBindingValue(N, S).
9.1.1.4.7 DeleteBinding ( N )
The DeleteBinding concrete method of a Global Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It can only delete bindings that have been explicitly designated as being subject to deletion. It performs the following steps when called:
If status is true and envRec.[[VarNames]] contains N, then
Remove N from envRec.[[VarNames]].
Return status.
Return true.
9.1.1.4.8 HasThisBinding ( )
The HasThisBinding concrete method of a Global Environment RecordenvRec takes no arguments and returns true. It performs the following steps when called:
The HasSuperBinding concrete method of a Global Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of a Global Environment RecordenvRec takes no arguments and returns undefined. It performs the following steps when called:
The HasVarDeclaration concrete method of a Global Environment RecordenvRec takes argument N (a String) and returns a Boolean. It determines if the argument identifier has a binding in this record that was created using a VariableStatement or a FunctionDeclaration. It performs the following steps when called:
Let varDeclaredNames be envRec.[[VarNames]].
If varDeclaredNames contains N, return true.
Return false.
9.1.1.4.13 HasLexicalDeclaration ( N )
The HasLexicalDeclaration concrete method of a Global Environment RecordenvRec takes argument N (a String) and returns a Boolean. It determines if the argument identifier has a binding in this record that was created using a lexical declaration such as a LexicalDeclaration or a ClassDeclaration. It performs the following steps when called:
Let DclRec be envRec.[[DeclarativeRecord]].
Return ! DclRec.HasBinding(N).
9.1.1.4.14 HasRestrictedGlobalProperty ( N )
The HasRestrictedGlobalProperty concrete method of a Global Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It determines if the argument identifier is the name of a property of the global object that must not be shadowed by a global lexical binding. It performs the following steps when called:
Let ObjRec be envRec.[[ObjectRecord]].
Let globalObject be ObjRec.[[BindingObject]].
Let existingProp be ? globalObject.[[GetOwnProperty]](N).
If existingProp is undefined, return false.
If existingProp.[[Configurable]] is true, return false.
Return true.
Note
Properties may exist upon a global object that were directly created rather than being declared using a var or function declaration. A global lexical binding may not be created that has the same name as a non-configurable property of the global object. The global property "undefined" is an example of such a property.
9.1.1.4.15 CanDeclareGlobalVar ( N )
The CanDeclareGlobalVar concrete method of a Global Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It determines if a corresponding CreateGlobalVarBinding call would succeed if called for the same argument N. Redundant var declarations and var declarations for pre-existing global object properties are allowed. It performs the following steps when called:
The CanDeclareGlobalFunction concrete method of a Global Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It determines if a corresponding CreateGlobalFunctionBinding call would succeed if called for the same argument N. It performs the following steps when called:
Let ObjRec be envRec.[[ObjectRecord]].
Let globalObject be ObjRec.[[BindingObject]].
Let existingProp be ? globalObject.[[GetOwnProperty]](N).
If existingProp is undefined, return ? IsExtensible(globalObject).
If existingProp.[[Configurable]] is true, return true.
If IsDataDescriptor(existingProp) is true and existingProp has attribute values { [[Writable]]: true, [[Enumerable]]: true }, return true.
Return false.
9.1.1.4.17 CreateGlobalVarBinding ( N, D )
The CreateGlobalVarBinding concrete method of a Global Environment RecordenvRec takes arguments N (a String) and D (a Boolean) and returns either a normal completion containingunused or a throw completion. It creates and initializes a mutable binding in the associated Object Environment Record and records the bound name in the associated [[VarNames]] List. If a binding already exists, it is reused and assumed to be initialized. It performs the following steps when called:
Global function declarations are always represented as own properties of the global object. If possible, an existing own property is reconfigured to have a standard set of attribute values. Step 7 is equivalent to what calling the InitializeBinding concrete method would do and if globalObject is a Proxy will produce the same sequence of Proxy trap calls.
9.1.1.5 Module Environment Records
A Module Environment Record is a Declarative Environment Record that is used to represent the outer scope of an ECMAScript Module. In additional to normal mutable and immutable bindings, Module Environment Records also provide immutable import bindings which are bindings that provide indirect access to a target binding that exists in another Environment Record.
Module Environment Records support all of the Declarative Environment Record methods listed in Table 16 and share the same specifications for all of those methods except for GetBindingValue, DeleteBinding, HasThisBinding and GetThisBinding. In addition, Module Environment Records support the methods listed in Table 22:
The behaviour of the additional concrete specification methods for Module Environment Records are defined by the following algorithms:
9.1.1.5.1 GetBindingValue ( N, S )
The GetBindingValue concrete method of a Module Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns the value of its bound identifier whose name is N. However, if the binding is an indirect binding the value of the target binding is returned. If the binding exists but is uninitialized a ReferenceError is thrown. It performs the following steps when called:
The HasThisBinding concrete method of a Module Environment RecordenvRec takes no arguments and returns true. It performs the following steps when called:
The CreateImportBinding concrete method of a Module Environment RecordenvRec takes arguments N (a String), M (a Module Record), and N2 (a String) and returns unused. It creates a new initialized immutable indirect binding for the name N. A binding must not already exist in this Environment Record for N. N2 is the name of a binding that exists in M's Module Environment Record. Accesses to the value of the new binding will indirectly access the bound value of the target binding. It performs the following steps when called:
Assert: envRec does not already have a binding for N.
Assert: When M.[[Environment]] is instantiated, it will have a direct binding for N2.
Create an immutable indirect binding in envRec for N that references M and N2 as its target binding and record that the binding is initialized.
The abstract operation NewObjectEnvironment takes arguments O (an Object), W (a Boolean), and E (an Environment Record or null) and returns an Object Environment Record. It performs the following steps when called:
The abstract operation NewFunctionEnvironment takes arguments F (an ECMAScript function) and newTarget (an Object or undefined) and returns a Function Environment Record. It performs the following steps when called:
If F.[[ThisMode]] is lexical, set env.[[ThisBindingStatus]] to lexical.
Else, set env.[[ThisBindingStatus]] to uninitialized.
Set env.[[NewTarget]] to newTarget.
Set env.[[OuterEnv]] to F.[[Environment]].
Return env.
9.1.2.5 NewGlobalEnvironment ( G, thisValue )
The abstract operation NewGlobalEnvironment takes arguments G (an Object) and thisValue (an Object) and returns a Global Environment Record. It performs the following steps when called:
The abstract operation ResolvePrivateIdentifier takes arguments privEnv (a PrivateEnvironment Record) and identifier (a String) and returns a Private Name. It performs the following steps when called:
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.
A realm is represented in this specification as a Realm Record with the fields specified in Table 24:
Template objects are canonicalized separately for each realm using its Realm Record's [[TemplateMap]]. Each [[Site]] value is a Parse Node that is a TemplateLiteral. The associated [[Array]] value is the corresponding template object that is passed to a tag function.
Note 1
Once a Parse Node becomes unreachable, the corresponding [[Array]] is also unreachable, and it would be unobservable if an implementation removed the pair from the [[TemplateMap]] list.
A map from the specifier strings imported by this realm to the resolved Module Record. The list does not contain two different Records with the same [[Specifier]].
Set fields of realmRec.[[Intrinsics]] with the values listed in Table 6. The field names are the names listed in column one of the table. The value of each field is a new object value fully and recursively populated with property values as defined by the specification of each object in clauses 19 through 28. All object property values are newly created object values. All values that are built-in function objects are created by performing CreateBuiltinFunction(steps, length, name, slots, realmRec, prototype) where steps is the definition of that function provided by this specification, name is the initial value of the function's "name" property, length is the initial value of the function's "length" property, slots is a list of the names, if any, of the function's specified internal slots, and prototype is the specified value of the function's [[Prototype]] internal slot. The creation of the intrinsics and their properties must be ordered to avoid any dependencies upon objects that have not yet been created.
The abstract operation SetRealmGlobalObject takes arguments realmRec (a Realm Record), globalObj (an Object or undefined), and thisValue (an Object or undefined) and returns unused. It performs the following steps when called:
Let desc be the fully populated data Property Descriptor for the property, containing the specified attributes for the property. For properties listed in 19.2, 19.3, or 19.4 the value of the [[Value]] attribute is the corresponding intrinsic object from realmRec.
An execution context is a specification device that is used to track the runtime evaluation of code by an ECMAScript implementation. At any point in time, there is at most one execution context per agent that is actually executing code. This is known as the agent's running execution context. All references to the running execution context in this specification denote the running execution context of the surrounding agent.
The execution context stack is used to track execution contexts. The running execution context is always the top element of this stack. A new execution context is created whenever control is transferred from the executable code associated with the currently running execution context to executable code that is not associated with that execution context. The newly created execution context is pushed onto the stack and becomes the running execution context.
An execution context contains whatever implementation specific state is necessary to track the execution progress of its associated code. Each execution context has at least the state components listed in Table 25.
Table 25: State Components for All Execution Contexts
Component
Purpose
code evaluation state
Any state needed to perform, suspend, and resume evaluation of the code associated with this execution context.
Evaluation of code by the running execution context may be suspended at various points defined within this specification. Once the running execution context has been suspended a different execution context may become the running execution context and commence evaluating its code. At some later time a suspended execution context may again become the running execution context and continue evaluating its code at the point where it had previously been suspended. Transition of the running execution context status among execution contexts usually occurs in stack-like last-in/first-out manner. However, some ECMAScript features require non-LIFO transitions of the running execution context.
In most situations only the running execution context (the top of the execution context stack) is directly manipulated by algorithms within this specification. Hence when the terms “LexicalEnvironment”, and “VariableEnvironment” are used without qualification they are in reference to those components of the running execution context.
An execution context is purely a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation. It is impossible for ECMAScript code to directly access or observe an execution context.
9.4.1 GetActiveScriptOrModule ( )
The abstract operation GetActiveScriptOrModule takes no arguments and returns a Script Record, a Module Record, or null. It is used to determine the running script or module, based on the running execution context. It performs the following steps when called:
If no such execution context exists, return null. Otherwise, return ec's ScriptOrModule.
9.4.2 ResolveBinding ( name [ , env ] )
The abstract operation ResolveBinding takes argument name (a String) and optional argument env (an Environment Record or undefined) and returns either a normal completion containing a Reference Record or a throw completion. It is used to determine the binding of name. env can be used to explicitly provide the Environment Record that is to be searched for the binding. It performs the following steps when called:
If the source text matched by the syntactic production that is being evaluated is contained in strict mode code, let strict be true; else let strict be false.
The result of ResolveBinding is always a Reference Record whose [[ReferencedName]] field is name.
9.4.3 GetThisEnvironment ( )
The abstract operation GetThisEnvironment takes no arguments and returns an Environment Record. It finds the Environment Record that currently supplies the binding of the keywordthis. It performs the following steps when called:
The abstract operation GetNewTarget takes no arguments and returns an Object or undefined. It determines the NewTarget value using the LexicalEnvironment of the running execution context. It performs the following steps when called:
The abstract operation GetGlobalObject takes no arguments and returns an Object. It returns the global object used by the currently running execution context. It performs the following steps when called:
A Job is an Abstract Closure with no parameters that initiates an ECMAScript computation when no other ECMAScript computation is currently in progress.
Jobs are scheduled for execution by ECMAScript host environments. This specification describes the host hookHostEnqueuePromiseJob to schedule one kind of job; hosts may define additional abstract operations which schedule jobs. Such operations accept a JobAbstract Closure as the parameter and schedule it to be performed at some future time. Their implementations must conform to the following requirements:
Host environments are not required to treat Jobs uniformly with respect to scheduling. For example, web browsers and Node.js treat Promise-handling Jobs as a higher priority than other work; future features may add Jobs that are not treated at such a high priority.
At any particular time, scriptOrModule (a Script Record, a Module Record, or null) is the active script or module if all of the following conditions are true:
The specific choice of Realm is up to the host environment. This initial execution context and Realm is only in use before any callback function is invoked. When a callback function related to a Job, like a Promise handler, is invoked, the invocation pushes its own execution context and Realm.
Particular kinds of Jobs have additional conformance requirements.
The WHATWG HTML specification (https://html.spec.whatwg.org/), for example, uses the host-defined value to propagate the incumbent settings object for Promise callbacks.
JobCallback Records have the fields listed in Table 28.
An implementation of HostMakeJobCallback must conform to the following requirements:
It must return a JobCallback Record whose [[Callback]] field is callback.
The default implementation of HostMakeJobCallback performs the following steps when called:
Return the JobCallback Record { [[Callback]]: callback, [[HostDefined]]: empty }.
ECMAScript hosts that are not web browsers must use the default implementation of HostMakeJobCallback.
Note
This is called at the time that the callback is passed to the function that is responsible for its being eventually scheduled and run. For example, promise.then(thenAction) calls MakeJobCallback on thenAction at the time of invoking Promise.prototype.then, not at the time of scheduling the reaction Job.
ECMAScript hosts that are not web browsers must use the default implementation of HostCallJobCallback.
9.5.4 HostEnqueuePromiseJob ( job, realm )
The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (a JobAbstract Closure) and realm (a Realm Record or null) and returns unused. It schedules job to be performed at some future time. The Abstract Closures used with this algorithm are intended to be related to the handling of Promises, or otherwise, to be scheduled with equal priority to Promise handling operations.
An implementation of HostEnqueuePromiseJob must conform to the requirements in 9.5 as well as the following:
Let scriptOrModule be GetActiveScriptOrModule() at the time HostEnqueuePromiseJob is invoked. If realm is not null, each time job is invoked the implementation must perform implementation-defined steps such that scriptOrModule is the active script or module at the time of job's invocation.
Jobs must run in the same order as the HostEnqueuePromiseJob invocations that scheduled them.
Note
The realm for Jobs returned by NewPromiseResolveThenableJob is usually the result of calling GetFunctionRealm on the thenfunction object. The realm for Jobs returned by NewPromiseReactionJob is usually the result of calling GetFunctionRealm on the handler if the handler is not undefined. If the handler is undefined, realm is null. For both kinds of Jobs, when GetFunctionRealm completes abnormally (i.e. called on a revoked Proxy), realm is the current Realm at the time of the GetFunctionRealm call. When the realm is null, no user ECMAScript code will be evaluated and no new ECMAScript objects (e.g. Error objects) will be created. The WHATWG HTML specification (https://html.spec.whatwg.org/), for example, uses realm to check for the ability to run script and for the entry concept.
9.6 InitializeHostDefinedRealm ( )
The abstract operation InitializeHostDefinedRealm takes no arguments and returns either a normal completion containingunused or a throw completion. It performs the following steps when called:
If the host requires that the this binding in realm's global scope return an object other than the global object, let thisValue be such an object created in a host-defined manner. Otherwise, let thisValue be undefined, indicating that realm's global this binding should be the global object.
The default value computed for the isLittleEndian parameter when it is needed by the algorithms GetValueFromBuffer and SetValueInBuffer. The choice is implementation-defined and should be the alternative that is most efficient for the implementation. Once the value has been observed it cannot change.
Initially a new empty List, representing the list of objects and/or symbols to be kept alive until the end of the current Job
Once the values of [[Signifier]], [[IsLockFree1]], and [[IsLockFree2]] have been observed by any agent in the agent cluster they cannot change.
Note 2
The values of [[IsLockFree1]] and [[IsLockFree2]] are not necessarily determined by the hardware, but may also reflect implementation choices that can vary over time and between ECMAScript implementations.
There is no [[IsLockFree4]] field: 4-byte atomic operations are always lock-free.
In practice, if an atomic operation is implemented with any type of lock the operation is not lock-free. Lock-free does not imply wait-free: there is no upper bound on how many machine steps may be required to complete a lock-free atomic operation.
That an atomic access of size n is lock-free does not imply anything about the (perceived) atomicity of non-atomic accesses of size n, specifically, non-atomic accesses may still be performed as a sequence of several separate memory accesses. See ReadSharedMemory and WriteSharedMemory for details.
Note 3
An agent is a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation.
9.7.1 AgentSignifier ( )
The abstract operation AgentSignifier takes no arguments and returns an agent signifier. It performs the following steps when called:
In some environments it may not be reasonable for a given agent to suspend. For example, in a web browser environment, it may be reasonable to disallow suspending a document's main event handling thread, while still allowing workers' event handling threads to suspend.
9.8 Agent Clusters
An agent cluster is a maximal set of agents that can communicate by operating on shared memory.
Note 1
Programs within different agents may share memory by unspecified means. At a minimum, the backing memory for SharedArrayBuffers can be shared among the agents in the cluster.
There may be agents that can communicate by message passing that cannot share memory; they are never in the same agent cluster.
The agents in a cluster need not all be alive at some particular point in time. If agentA creates another agentB, after which A terminates and B creates agentC, the three agents are in the same cluster if A could share some memory with B and B could share some memory with C.
All agents within a cluster must have the same value for the [[LittleEndian]] field in their respective Agent Records.
Note 3
If different agents within an agent cluster have different values of [[LittleEndian]] it becomes hard to use shared memory for multi-byte data.
All agents within a cluster must have the same values for the [[IsLockFree1]] field in their respective Agent Records; similarly for the [[IsLockFree2]] field.
All agents within a cluster must have different values for the [[Signifier]] field in their respective Agent Records.
An embedding may deactivate (stop forward progress) or activate (resume forward progress) an agent without the agent's knowledge or cooperation. If the embedding does so, it must not leave some agents in the cluster active while other agents in the cluster are deactivated indefinitely.
Note 4
The purpose of the preceding restriction is to avoid a situation where an agent deadlocks or starves because another agent has been deactivated. For example, if an HTML shared worker that has a lifetime independent of documents in any windows were allowed to share memory with the dedicated worker of such an independent document, and the document and its dedicated worker were to be deactivated while the dedicated worker holds a lock (say, the document is pushed into its window's history), and the shared worker then tries to acquire the lock, then the shared worker will be blocked until the dedicated worker is activated again, if ever. Meanwhile other workers trying to access the shared worker from other windows will starve.
The implication of the restriction is that it will not be possible to share memory between agents that don't belong to the same suspend/wake collective within the embedding.
An embedding may terminate an agent without any of the agent's cluster's other agents' prior knowledge or cooperation. If an agent is terminated not by programmatic action of its own or of another agent in the cluster but by forces external to the cluster, then the embedding must choose one of two strategies: Either terminate all the agents in the cluster, or provide reliable APIs that allow the agents in the cluster to coordinate so that at least one remaining member of the cluster will be able to detect the termination, with the termination data containing enough information to identify the agent that was terminated.
Note 5
Examples of that type of termination are: operating systems or users terminating agents that are running in separate processes; the embedding itself terminating an agent that is running in-process with the other agents when per-agent resource accounting indicates that the agent is runaway.
An agent cluster is a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation.
9.9 Forward Progress
For an agent to make forward progress is for it to perform an evaluation step according to this specification.
An agent becomes blocked when its running execution context waits synchronously and indefinitely for an external event. Only agents whose Agent Record's [[CanBlock]] field is true can become blocked in this sense. An unblockedagent is one that is not blocked.
Implementations must ensure that:
every unblocked agent with a dedicated executing thread eventually makes forward progress
an agent does not cause another agent to become blocked except via explicit APIs that provide blocking.
Note
This, along with the liveness guarantee in the memory model, ensures that all SeqCst writes eventually become observable to all agents.
9.10 Processing Model of WeakRef and FinalizationRegistry Targets
9.10.1 Objectives
This specification does not make any guarantees that any object or symbol 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 WeakRefs and FinalizationRegistrys is based on two operations which happen at particular points in time:
When WeakRef.prototype.deref is called, the referent (if undefined is not returned) is kept alive so that subsequent, synchronous accesses also return the same value. This list is reset when synchronous work is done using the ClearKeptObjects abstract operation.
Some ECMAScript implementations include garbage collector implementations which run in the background, including when ECMAScript is idle. Letting the host environment schedule CleanupFinalizationRegistry allows it to resume ECMAScript execution in order to run finalizer work, which may free up held values, reducing overall memory usage.
9.10.2 Liveness
For some set of objects and/or symbols 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.
Note 1
WeakRef-obliviousness, together with liveness, capture two notions. One, that a WeakRef itself does not keep its referent alive. Two, that cycles in liveness does not imply that a value is live. To be concrete, if determining v's liveness depends on determining the liveness of a WeakRef referent, r, r's liveness cannot assume v's liveness, which would be circular reasoning.
Note 2
WeakRef-obliviousness is defined on sets of objects or symbols instead of individual values to account for cycles. If it were defined on individual values, then a WeakRef referent in a cycle will be considered live even though its identity is only observed via other WeakRef referents in the cycle.
Note 3
Colloquially, we say that an individual object or symbol is live if every set containing it is live.
At any point during evaluation, a set of objects and/or symbols 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 identity of any value in S.
Note 4
The second condition above intends to capture the intuition that a value is live if its identity is observable via non-WeakRef means. A value's identity may be observed by observing a strict equality comparison or observing the value being used as key in a Map.
Note 5
Presence of an object or a symbol in a field, an internal slot, or a property does not imply that the value is live. For example if the value 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.
Note 6
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.
9.10.3 Execution
At any time, if a set of objects and/or symbols S is not live, an ECMAScript implementation may perform the following steps atomically:
For each element value of S, do
For each WeakRefref such that ref.[[WeakRefTarget]] is value, do
Set ref.[[WeakRefTarget]] to empty.
For each FinalizationRegistryfg such that fg.[[Cells]] contains a Recordcell such that cell.[[WeakRefTarget]] is value, do
For each WeakMap map such that map.[[WeakMapData]] contains a Recordr such that r.[[Key]] is value, do
Set r.[[Key]] to empty.
Set r.[[Value]] to empty.
For each WeakSet set such that set.[[WeakSetData]] contains value, do
Replace the element of set.[[WeakSetData]] whose value is value with an element whose value is empty.
Note 1
Together with the definition of liveness, this clause prescribes optimizations that an implementation may apply regarding WeakRefs.
It is possible to access an object without observing its identity. Optimizations such as dead variable elimination and scalar replacement on properties of non-escaping objects whose identity is not observed are allowed. These optimizations are thus allowed to observably empty WeakRefs that point to such objects.
On the other hand, if an object's identity is observable, and that object is in the [[WeakRefTarget]] internal slot of a WeakRef, optimizations such as rematerialization that observably empty the WeakRef are prohibited.
Implementations are not obligated to empty WeakRefs for maximal sets of non-live objects or symbols.
If an implementation chooses a non-live set S in which to empty WeakRefs, this definition requires that it empties WeakRefs for all values in S simultaneously. In other words, it is not conformant for an implementation to empty a WeakRef pointing to a value v without emptying out other WeakRefs that, if not emptied, could result in an execution that observes the value of v.
The host-defined abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument finalizationRegistry (a FinalizationRegistry) and returns unused.
Let cleanupJob be a new JobAbstract Closure with no parameters that captures finalizationRegistry and performs the following steps when called:
An implementation of HostEnqueueFinalizationRegistryCleanupJob schedules cleanupJob to be performed at some future time, if possible. It must also conform to the requirements in 9.5.
9.11 ClearKeptObjects ( )
The abstract operation ClearKeptObjects takes no arguments and returns unused. ECMAScript implementations are expected to call ClearKeptObjects when a synchronous sequence of ECMAScript executions completes. It performs the following steps when called:
When the abstract operation AddToKeptObjects is called with a target object or symbol, it adds the target to a list that will point strongly at the target until ClearKeptObjects is called.
Assert: finalizationRegistry has [[Cells]] and [[CleanupCallback]] internal slots.
Let callback be finalizationRegistry.[[CleanupCallback]].
While finalizationRegistry.[[Cells]] contains a Recordcell such that cell.[[WeakRefTarget]] is empty, an implementation may perform the following steps:
The abstract operation CanBeHeldWeakly takes argument v (an ECMAScript language value) and returns a Boolean. It returns true if and only if v is suitable for use as a weak reference. Only values that are suitable for use as a weak reference may be a key of a WeakMap, an element of a WeakSet, the target of a WeakRef, or one of the targets of a FinalizationRegistry. It performs the following steps when called:
A language value without language identity can be manifested without prior reference and is unsuitable for use as a weak reference. A Symbol value produced by Symbol.for, unlike other Symbol values, does not have language identity and is unsuitable for use as a weak reference. Well-known symbols are likely to never be collected, but are nonetheless treated as suitable for use as a weak reference because they are limited in number and therefore manageable by a variety of implementation approaches. However, any value associated to a well-known symbol in a live WeakMap is unlikely to be collected and could “leak” memory resources in implementations.