# 9 Executable Code and Execution Contexts

# 9.1 Environment Records

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.

# 9.1.1 The Environment Record Type Hierarchy

Environment Records can be thought of as existing in a simple object-oriented hierarchy where Environment Record is an abstract class with three concrete subclasses: Declarative Environment Record, Object Environment Record, and Global Environment Record. Function Environment Records and Module Environment Records are subclasses of Declarative Environment Record.

- Environment Record (abstract)

  - A Declarative Environment Record is used to define the effect of ECMAScript language syntactic elements such as FunctionDeclarations, VariableDeclarations, and Catch clauses that directly associate identifier bindings with ECMAScript language 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.

    - A Module Environment Record contains the bindings for the top-level declarations of a Module. It also contains the bindings that are explicitly imported by the Module. Its [[OuterEnv]] is a Global Environment Record.

  - 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 14. These abstract methods have distinct concrete algorithms for each of the concrete subclasses.

Table 14: Abstract Methods of Environment Records

Method | Purpose | Definitions
--- | --- | ---
HasBinding ( N ) | The abstract method HasBinding takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It determines if an Environment Record has a binding for N. | It has concrete definitions in the following types: 9.1.1.1.1 Declarative Environment Record 9.1.1.2.1 Object Environment Record 9.1.1.4.1 Global Environment Record
CreateMutableBinding ( N, D ) | The abstract method CreateMutableBinding takes arguments N (a String) and D (a Boolean) and returns either a normal completion containing unused or a throw completion. It creates a new but uninitialized mutable binding in an Environment Record. N is the text of the bound name. If D is true the binding may be subsequently deleted. | It has concrete definitions in the following types: 9.1.1.1.2 Declarative Environment Record 9.1.1.2.2 Object Environment Record 9.1.1.4.2 Global Environment Record
CreateImmutableBinding ( N, S ) | The abstract method CreateImmutableBinding takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing unused or a throw completion. It creates a new but uninitialized immutable binding in an Environment Record. 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. | It has concrete definitions in the following types: 9.1.1.1.3 Declarative Environment Record 9.1.1.4.3 Global Environment Record
InitializeBinding ( N, V ) | The abstract method InitializeBinding takes arguments N (a String) and V (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It sets the value of an already existing but uninitialized binding in an Environment Record. N is the text of the bound name. V is the value for the binding. | It has concrete definitions in the following types: 9.1.1.1.4 Declarative Environment Record 9.1.1.2.4 Object Environment Record 9.1.1.4.4 Global Environment Record
SetMutableBinding ( N, V, S ) | The abstract method SetMutableBinding takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containing unused or a throw completion. It sets the value of an already existing mutable binding in an Environment Record. N is the text of the bound name. V is the value for the binding. If S is true and the binding cannot be set, this will throw a TypeError exception. | It has concrete definitions in the following types: 9.1.1.1.5 Declarative Environment Record 9.1.1.2.5 Object Environment Record 9.1.1.4.5 Global Environment Record
GetBindingValue ( N, S ) | The abstract method GetBindingValue 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 an already existing binding from an Environment Record. 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, this will throw a ReferenceError exception. If the binding exists but is uninitialized a ReferenceError is thrown, regardless of the value of S. | It has concrete definitions in the following types: 9.1.1.1.6 Declarative Environment Record 9.1.1.2.6 Object Environment Record 9.1.1.4.6 Global Environment Record 9.1.1.5.1 Module Environment Record
DeleteBinding ( N ) | The abstract method DeleteBinding takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It deletes a binding from an Environment Record. N is the text of the bound name. If a binding for N exists, this removes the binding and returns true. If the binding exists but cannot be removed, this returns false. If the binding does not exist, this returns true. | It has concrete definitions in the following types: 9.1.1.1.7 Declarative Environment Record 9.1.1.2.7 Object Environment Record 9.1.1.4.7 Global Environment Record
HasThisBinding ( ) | The abstract method HasThisBinding takes no arguments and returns a Boolean. It determines if an Environment Record establishes a `this` binding. This returns true if it does and false if it does not. | It has concrete definitions in the following types: 9.1.1.1.8 Declarative Environment Record 9.1.1.2.8 Object Environment Record 9.1.1.3.2 Function Environment Record 9.1.1.4.8 Global Environment Record 9.1.1.5.3 Module Environment Record
GetThisBinding ( ) | The abstract method GetThisBinding takes no arguments and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns the value of this Environment Record's `this` binding. It throws a ReferenceError if the `this` binding has not been initialized. | It has concrete definitions in the following types: 9.1.1.3.3 Function Environment Record 9.1.1.4.9 Global Environment Record 9.1.1.5.4 Module Environment Record
HasSuperBinding ( ) | The abstract method HasSuperBinding takes no arguments and returns a Boolean. It determines if an Environment Record establishes a `super` method binding. This returns true if it does and false if it does not. If it returns true it implies that the Environment Record is a Function Environment Record, although the reverse implication does not hold. | It has concrete definitions in the following types: 9.1.1.1.10 Declarative Environment Record 9.1.1.2.10 Object Environment Record 9.1.1.3.4 Function Environment Record 9.1.1.4.10 Global Environment Record
WithBaseObject ( ) | The abstract method WithBaseObject takes no arguments and returns an Object or undefined. If this Environment Record is associated with a `with` statement, it returns the with object. Otherwise, it returns undefined. | It has concrete definitions in the following types: 9.1.1.1.11 Declarative Environment Record 9.1.1.2.11 Object Environment Record 9.1.1.4.11 Global Environment Record

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

# 9.1.1.1.1 HasBinding ( N )

The HasBinding concrete method of a Declarative Environment Record envRec 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:

1. If envRec has a binding for N, return true.
2. Return false.

# 9.1.1.1.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of a Declarative Environment Record envRec takes arguments N (a String) and D (a Boolean) and returns a normal completion containing unused. 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:

1. Assert: envRec does not already have a binding for N.
2. 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.
3. Return unused.

# 9.1.1.1.3 CreateImmutableBinding ( N, S )

The CreateImmutableBinding concrete method of a Declarative Environment Record envRec takes arguments N (a String) and S (a Boolean) and returns a normal completion containing unused. 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:

1. Assert: envRec does not already have a binding for N.
2. 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.
3. Return unused.

# 9.1.1.1.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of a Declarative Environment Record envRec takes arguments N (a String) and V (an ECMAScript language value) and returns a normal completion containing unused. 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:

1. Assert: envRec must have an uninitialized binding for N.
2. Set the bound value for N in envRec to V.
3. Record that the binding for N in envRec has been initialized.
4. Return unused.

# 9.1.1.1.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of a Declarative Environment Record envRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containing unused 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:

1. If envRec does not have a binding for N, then
   1. If S is true, throw a ReferenceError exception.
   2. Perform ! envRec.CreateMutableBinding(N, true).
   3. Perform ! envRec.InitializeBinding(N, V).
   4. Return unused.
2. If the binding for N in envRec is a strict binding, set S to true.
3. If the binding for N in envRec has not yet been initialized, then
   1. Throw a ReferenceError exception.
4. Else if the binding for N in envRec is a mutable binding, then
   1. Change its bound value to V.
5. Else,
   1. Assert: This is an attempt to change the value of an immutable binding.
   2. If S is true, throw a TypeError exception.
6. Return unused.

Note

An example of ECMAScript code that results in a missing binding at step 1 is:

    function f() { eval("var x; x = (delete x, 0);"); }

# 9.1.1.1.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of a Declarative Environment Record envRec 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:

1. Assert: envRec has a binding for N.
2. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
3. Return the value currently bound to N in envRec.

# 9.1.1.1.7 DeleteBinding ( N )

The DeleteBinding concrete method of a Declarative Environment Record envRec 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:

1. Assert: envRec has a binding for N.
2. If the binding for N in envRec cannot be deleted, return false.
3. Remove the binding for N from envRec.
4. Return true.

# 9.1.1.1.8 HasThisBinding ( )

The HasThisBinding concrete method of a Declarative Environment Record envRec takes no arguments and returns false. It performs the following steps when called:

1. Return false.

Note

A regular Declarative Environment Record (i.e., one that is neither a Function Environment Record nor a Module Environment Record) does not provide a `this` binding.

# 9.1.1.1.9 GetThisBinding ( )

The GetThisBinding concrete method of a Declarative Environment Record is never used within this specification.

# 9.1.1.1.10 HasSuperBinding ( )

The HasSuperBinding concrete method of a Declarative Environment Record envRec takes no arguments and returns false. It performs the following steps when called:

1. Return false.

Note

A regular Declarative Environment Record (i.e., one that is neither a Function Environment Record nor a Module Environment Record) does not provide a `super` binding.

# 9.1.1.1.11 WithBaseObject ( )

The WithBaseObject concrete method of a Declarative Environment Record envRec takes no arguments and returns undefined. It performs the following steps when called:

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

Table 15: Additional Fields of Object Environment Records

Field Name | Value | Meaning
--- | --- | ---
[[BindingObject]] | an Object | The binding object of this Environment Record.
[[IsWithEnvironment]] | a Boolean | Indicates whether this Environment Record is created for a `with` statement.

# 9.1.1.2.1 HasBinding ( N )

The HasBinding concrete method of an Object Environment Record envRec 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:

1. Let bindingObject be envRec.[[BindingObject]].
2. Let foundBinding be ? HasProperty(bindingObject, N).
3. If foundBinding is false, return false.
4. If envRec.[[IsWithEnvironment]] is false, return true.
5. Let unscopables be ? Get(bindingObject, %Symbol.unscopables%).
6. If unscopables is an Object, then
   1. Let blocked be ToBoolean(? Get(unscopables, N)).
   2. If blocked is true, return false.
7. Return true.

# 9.1.1.2.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of an Object Environment Record envRec takes arguments N (a String) and D (a Boolean) and returns either a normal completion containing unused 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:

1. Let bindingObject be envRec.[[BindingObject]].
2. Perform ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
3. 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.

# 9.1.1.2.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of an Object Environment Record envRec takes arguments N (a String) and V (an ECMAScript language value) and returns either a normal completion containing unused 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. It performs the following steps when called:

1. Perform ? envRec.SetMutableBinding(N, V, false).
2. Return unused.

Note

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 Record envRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containing unused 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:

1. Let bindingObject be envRec.[[BindingObject]].
2. Let stillExists be ? HasProperty(bindingObject, N).
3. If stillExists is false and S is true, throw a ReferenceError exception.
4. Perform ? Set(bindingObject, N, V, S).
5. Return unused.

# 9.1.1.2.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of an Object Environment Record envRec 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:

1. Let bindingObject be envRec.[[BindingObject]].
2. Let value be ? HasProperty(bindingObject, N).
3. If value is false, then
   1. If S is false, return undefined.
   2. Throw a ReferenceError exception.
4. Return ? Get(bindingObject, N).

# 9.1.1.2.7 DeleteBinding ( N )

The DeleteBinding concrete method of an Object Environment Record envRec 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:

1. Let bindingObject be envRec.[[BindingObject]].
2. Return ? bindingObject.[[Delete]](N).

# 9.1.1.2.8 HasThisBinding ( )

The HasThisBinding concrete method of an Object Environment Record envRec takes no arguments and returns false. It performs the following steps when called:

1. Return false.

Note

Object Environment Records do not provide a `this` binding.

# 9.1.1.2.9 GetThisBinding ( )

The GetThisBinding concrete method of an Object Environment Record is never used within this specification.

# 9.1.1.2.10 HasSuperBinding ( )

The HasSuperBinding concrete method of an Object Environment Record envRec takes no arguments and returns false. It performs the following steps when called:

1. Return false.

Note

Object Environment Records do not provide a `super` binding.

# 9.1.1.2.11 WithBaseObject ( )

The WithBaseObject concrete method of an Object Environment Record envRec takes no arguments and returns an Object or undefined. It performs the following steps when called:

1. If envRec.[[IsWithEnvironment]] is true, return envRec.[[BindingObject]].
2. 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 16.

Table 16: Additional Fields of Function Environment Records

Field Name | Value | Meaning
--- | --- | ---
[[ThisValue]] | an ECMAScript language value | This is the this value used for this invocation of the function.
[[ThisBindingStatus]] | lexical, initialized, or uninitialized | If the value is lexical, this is an ArrowFunction and does not have a local this value.
[[FunctionObject]] | an ECMAScript function object | The function object whose invocation caused this Environment Record to be created.
[[NewTarget]] | a constructor or undefined | 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 14 and share the same specifications for all of those methods except for HasThisBinding, GetThisBinding, and HasSuperBinding.

# 9.1.1.3.1 BindThisValue ( envRec, V )

The abstract operation BindThisValue takes arguments envRec (a Function Environment Record) and V (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It sets the envRec.[[ThisValue]] and records that it has been initialized. It performs the following steps when called:

1. Assert: envRec.[[ThisBindingStatus]] is not lexical.
2. If envRec.[[ThisBindingStatus]] is initialized, throw a ReferenceError exception.
3. Set envRec.[[ThisValue]] to V.
4. Set envRec.[[ThisBindingStatus]] to initialized.
5. Return unused.

# 9.1.1.3.2 HasThisBinding ( )

The HasThisBinding concrete method of a Function Environment Record envRec takes no arguments and returns a Boolean. It performs the following steps when called:

1. If envRec.[[ThisBindingStatus]] is lexical, return false.
2. Return true.

# 9.1.1.3.3 GetThisBinding ( )

The GetThisBinding concrete method of a Function Environment Record envRec takes no arguments and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

1. Assert: envRec.[[ThisBindingStatus]] is not lexical.
2. If envRec.[[ThisBindingStatus]] is uninitialized, throw a ReferenceError exception.
3. Return envRec.[[ThisValue]].

# 9.1.1.3.4 HasSuperBinding ( )

The HasSuperBinding concrete method of a Function Environment Record envRec takes no arguments and returns a Boolean. It performs the following steps when called:

1. If envRec.[[ThisBindingStatus]] is lexical, return false.
2. If envRec.[[FunctionObject]].[[HomeObject]] is undefined, return false.
3. Return true.

# 9.1.1.3.5 GetSuperBase ( envRec )

The abstract operation GetSuperBase takes argument envRec (a Function Environment Record) and returns an Object, null, or undefined. It returns the object that is the base for `super` property accesses bound in envRec. The value undefined indicates that such accesses will produce runtime errors. It performs the following steps when called:

1. Let home be envRec.[[FunctionObject]].[[HomeObject]].
2. If home is undefined, return undefined.
3. Assert: home is an ordinary object.
4. Return ! home.[[GetPrototypeOf]]().

# 9.1.1.4 Global Environment Records

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.

A Global Environment Record is logically a single record but it is specified as a composite encapsulating an Object Environment Record and a Declarative Environment Record. The Object Environment Record has as its base object the global object of the associated Realm Record. This global object is the value returned by the Global Environment Record's GetThisBinding concrete method. The Object Environment Record component of a Global Environment Record contains the bindings for all built-in globals (clause 19) and all bindings introduced by a FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, or VariableStatement contained in global code. The bindings for all other ECMAScript declarations in global code are contained in the Declarative Environment Record component of the Global Environment Record.

Properties may be created directly on a global object. Hence, the Object Environment Record component of a Global Environment Record may contain both bindings created explicitly by FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, or VariableDeclaration declarations and bindings created implicitly as properties of the global object. In order to identify which bindings were explicitly created using declarations, a Global Environment Record maintains a list of the names bound using the CreateGlobalVarBinding and CreateGlobalFunctionBinding abstract operations.

Global Environment Records have the additional fields listed in Table 17.

Table 17: Additional Fields of Global Environment Records

Field Name | Value | Meaning
--- | --- | ---
[[ObjectRecord]] | an Object Environment Record | Binding object is the global object. It contains global built-in bindings as well as FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, and VariableDeclaration bindings in global code for the associated realm.
[[GlobalThisValue]] | an Object | The value returned by `this` in global scope. Hosts may provide any ECMAScript Object value.
[[DeclarativeRecord]] | a Declarative Environment Record | Contains bindings for all declarations in global code for the associated realm code except for FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, and VariableDeclaration bindings.

# 9.1.1.4.1 HasBinding ( N )

The HasBinding concrete method of a Global Environment Record envRec 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:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. If ! DclRec.HasBinding(N) is true, return true.
3. Let ObjRec be envRec.[[ObjectRecord]].
4. Return ? ObjRec.HasBinding(N).

# 9.1.1.4.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of a Global Environment Record envRec takes arguments N (a String) and D (a Boolean) and returns either a normal completion containing unused 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:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
3. Return ! DclRec.CreateMutableBinding(N, D).

# 9.1.1.4.3 CreateImmutableBinding ( N, S )

The CreateImmutableBinding concrete method of a Global Environment Record envRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing unused 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:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
3. Return ! DclRec.CreateImmutableBinding(N, S).

# 9.1.1.4.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of a Global Environment Record envRec takes arguments N (a String) and V (an ECMAScript language value) and returns either a normal completion containing unused 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:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. If ! DclRec.HasBinding(N) is true, then
   1. Return ! DclRec.InitializeBinding(N, V).
3. Assert: If the binding exists, it must be in the Object Environment Record.
4. Let ObjRec be envRec.[[ObjectRecord]].
5. Return ? ObjRec.InitializeBinding(N, V).

# 9.1.1.4.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of a Global Environment Record envRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containing unused 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:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. If ! DclRec.HasBinding(N) is true, then
   1. Return ? DclRec.SetMutableBinding(N, V, S).
3. Let ObjRec be envRec.[[ObjectRecord]].
4. Return ? ObjRec.SetMutableBinding(N, V, S).

# 9.1.1.4.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of a Global Environment Record envRec 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:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. If ! DclRec.HasBinding(N) is true, then
   1. Return ? DclRec.GetBindingValue(N, S).
3. Let ObjRec be envRec.[[ObjectRecord]].
4. Return ? ObjRec.GetBindingValue(N, S).

# 9.1.1.4.7 DeleteBinding ( N )

The DeleteBinding concrete method of a Global Environment Record envRec 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:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. If ! DclRec.HasBinding(N) is true, then
   1. Return ! DclRec.DeleteBinding(N).
3. Let ObjRec be envRec.[[ObjectRecord]].
4. Let globalObject be ObjRec.[[BindingObject]].
5. Let existingProp be ? HasOwnProperty(globalObject, N).
6. If existingProp is true, then
   1. Return ? ObjRec.DeleteBinding(N).
7. Return true.

# 9.1.1.4.8 HasThisBinding ( )

The HasThisBinding concrete method of a Global Environment Record envRec takes no arguments and returns true. It performs the following steps when called:

1. Return true.

Note

Global Environment Records always provide a `this` binding.

# 9.1.1.4.9 GetThisBinding ( )

The GetThisBinding concrete method of a Global Environment Record envRec takes no arguments and returns a normal completion containing an Object. It performs the following steps when called:

1. Return envRec.[[GlobalThisValue]].

# 9.1.1.4.10 HasSuperBinding ( )

The HasSuperBinding concrete method of a Global Environment Record envRec takes no arguments and returns false. It performs the following steps when called:

1. Return false.

Note

Global Environment Records do not provide a `super` binding.

# 9.1.1.4.11 WithBaseObject ( )

The WithBaseObject concrete method of a Global Environment Record envRec takes no arguments and returns undefined. It performs the following steps when called:

1. Return undefined.

# 9.1.1.4.12 HasLexicalDeclaration ( envRec, N )

The abstract operation HasLexicalDeclaration takes arguments envRec (a Global Environment Record) and N (a String) and returns a Boolean. It determines if the argument identifier has a binding in envRec that was created using a lexical declaration such as a LexicalDeclaration or a ClassDeclaration. It performs the following steps when called:

1. Let DclRec be envRec.[[DeclarativeRecord]].
2. Return ! DclRec.HasBinding(N).

# 9.1.1.4.13 HasRestrictedGlobalProperty ( envRec, N )

The abstract operation HasRestrictedGlobalProperty takes arguments envRec (a Global Environment Record) and 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:

1. Let ObjRec be envRec.[[ObjectRecord]].
2. Let globalObject be ObjRec.[[BindingObject]].
3. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
4. If existingProp is undefined, return false.
5. If existingProp.[[Configurable]] is true, return false.
6. 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.14 CanDeclareGlobalVar ( envRec, N )

The abstract operation CanDeclareGlobalVar takes arguments envRec (a Global Environment Record) and 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:

1. Let ObjRec be envRec.[[ObjectRecord]].
2. Let globalObject be ObjRec.[[BindingObject]].
3. Let hasProperty be ? HasOwnProperty(globalObject, N).
4. If hasProperty is true, return true.
5. Return ? IsExtensible(globalObject).

# 9.1.1.4.15 CanDeclareGlobalFunction ( envRec, N )

The abstract operation CanDeclareGlobalFunction takes arguments envRec (a Global Environment Record) and 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:

1. Let ObjRec be envRec.[[ObjectRecord]].
2. Let globalObject be ObjRec.[[BindingObject]].
3. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
4. If existingProp is undefined, return ? IsExtensible(globalObject).
5. If existingProp.[[Configurable]] is true, return true.
6. If IsDataDescriptor(existingProp) is true and existingProp has attribute values { [[Writable]]: true, [[Enumerable]]: true }, return true.
7. Return false.

# 9.1.1.4.16 CreateGlobalVarBinding ( envRec, N, D )

The abstract operation CreateGlobalVarBinding takes arguments envRec (a Global Environment Record), N (a String), and D (a Boolean) and returns either a normal completion containing unused or a throw completion. It creates and initializes a mutable binding in the associated Object Environment Record. If a binding already exists, it is reused and assumed to be initialized. It performs the following steps when called:

1. Let ObjRec be envRec.[[ObjectRecord]].
2. Let globalObject be ObjRec.[[BindingObject]].
3. Let hasProperty be ? HasOwnProperty(globalObject, N).
4. Let extensible be ? IsExtensible(globalObject).
5. If hasProperty is false and extensible is true, then
   1. Perform ? ObjRec.CreateMutableBinding(N, D).
   2. Perform ? ObjRec.InitializeBinding(N, undefined).
6. Return unused.

# 9.1.1.4.17 CreateGlobalFunctionBinding ( envRec, N, V, D )

The abstract operation CreateGlobalFunctionBinding takes arguments envRec (a Global Environment Record), N (a String), V (an ECMAScript language value), and D (a Boolean) and returns either a normal completion containing unused or a throw completion. It creates and initializes a mutable binding in the associated Object Environment Record. If a binding already exists, it is replaced. It performs the following steps when called:

1. Let ObjRec be envRec.[[ObjectRecord]].
2. Let globalObject be ObjRec.[[BindingObject]].
3. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
4. If existingProp is undefined or existingProp.[[Configurable]] is true, then
   1. Let desc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }.
5. Else,
   1. Let desc be the PropertyDescriptor { [[Value]]: V }.
6. Perform ? DefinePropertyOrThrow(globalObject, N, desc).
7. Perform ? Set(globalObject, N, V, false).
8. Return unused.

Note

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 14 and share the same specifications for all of those methods except for GetBindingValue, DeleteBinding, HasThisBinding, and GetThisBinding.

# 9.1.1.5.1 GetBindingValue ( N, S )

The GetBindingValue concrete method of a Module Environment Record envRec 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:

1. Assert: S is true.
2. Assert: envRec has a binding for N.
3. If the binding for N is an indirect binding, then
   1. Let M and N2 be the indirection values provided when this binding for N was created.
   2. Let targetEnv be M.[[Environment]].
   3. If targetEnv is empty, throw a ReferenceError exception.
   4. Return ? targetEnv.GetBindingValue(N2, true).
4. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
5. Return the value currently bound to N in envRec.

Note

S will always be true because a Module is always strict mode code.

# 9.1.1.5.2 DeleteBinding ( N )

The DeleteBinding concrete method of a Module Environment Record is never used within this specification.

Note

Module Environment Records are only used within strict code and an early error rule prevents the delete operator, in strict code, from being applied to a Reference Record that would resolve to a Module Environment Record binding. See 13.5.1.1.

# 9.1.1.5.3 HasThisBinding ( )

The HasThisBinding concrete method of a Module Environment Record envRec takes no arguments and returns true. It performs the following steps when called:

1. Return true.

Note

Module Environment Records always provide a `this` binding.

# 9.1.1.5.4 GetThisBinding ( )

The GetThisBinding concrete method of a Module Environment Record envRec takes no arguments and returns a normal completion containing undefined. It performs the following steps when called:

1. Return undefined.

# 9.1.1.5.5 CreateImportBinding ( envRec, N, M, N2 )

The abstract operation CreateImportBinding takes arguments envRec (a Module Environment Record), 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 envRec 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:

1. Assert: envRec does not already have a binding for N.
2. Assert: When M.[[Environment]] is instantiated, it will have a direct binding for N2.
3. 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.
4. Return unused.

# 9.1.2 Environment Record Operations

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

# 9.1.2.1 GetIdentifierReference ( env, name, strict )

The abstract operation GetIdentifierReference takes arguments env (an Environment Record or null), name (a String), and strict (a Boolean) and returns either a normal completion containing a Reference Record or a throw completion. It performs the following steps when called:

1. If env is null, then
   1. Return the Reference Record { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }.
2. Let exists be ? env.HasBinding(name).
3. If exists is true, then
   1. Return the Reference Record { [[Base]]: env, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }.
4. Let outer be env.[[OuterEnv]].
5. Return ? GetIdentifierReference(outer, name, strict).

# 9.1.2.2 NewDeclarativeEnvironment ( E )

The abstract operation NewDeclarativeEnvironment takes argument E (an Environment Record or null) and returns a Declarative Environment Record. It performs the following steps when called:

1. Let env be a new Declarative Environment Record containing no bindings.
2. Set env.[[OuterEnv]] to E.
3. Return env.

# 9.1.2.3 NewObjectEnvironment ( O, W, E )

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:

1. Let env be a new Object Environment Record.
2. Set env.[[BindingObject]] to O.
3. Set env.[[IsWithEnvironment]] to W.
4. Set env.[[OuterEnv]] to E.
5. Return env.

# 9.1.2.4 NewFunctionEnvironment ( F, newTarget )

The abstract operation NewFunctionEnvironment takes arguments F (an ECMAScript function object) and newTarget (an Object or undefined) and returns a Function Environment Record. It performs the following steps when called:

1. Let env be a new Function Environment Record containing no bindings.
2. Set env.[[FunctionObject]] to F.
3. If F.[[ThisMode]] is lexical, set env.[[ThisBindingStatus]] to lexical.
4. Else, set env.[[ThisBindingStatus]] to uninitialized.
5. Set env.[[NewTarget]] to newTarget.
6. Set env.[[OuterEnv]] to F.[[Environment]].
7. 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:

1. Let objRec be NewObjectEnvironment(G, false, null).
2. Let dclRec be NewDeclarativeEnvironment(null).
3. Let env be a new Global Environment Record.
4. Set env.[[ObjectRecord]] to objRec.
5. Set env.[[GlobalThisValue]] to thisValue.
6. Set env.[[DeclarativeRecord]] to dclRec.
7. Set env.[[OuterEnv]] to null.
8. Return env.

# 9.1.2.6 NewModuleEnvironment ( E )

The abstract operation NewModuleEnvironment takes argument E (an Environment Record) and returns a Module Environment Record. It performs the following steps when called:

1. Let env be a new Module Environment Record containing no bindings.
2. Set env.[[OuterEnv]] to E.
3. Return env.

# 9.2 PrivateEnvironment Records

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

Each PrivateEnvironment Record has the fields defined in Table 18.

Table 18: PrivateEnvironment Record Fields

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

# 9.2.1 PrivateEnvironment Record Operations

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

# 9.2.1.1 NewPrivateEnvironment ( outerPrivateEnv )

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

1. Let names be a new empty List.
2. Return the PrivateEnvironment Record { [[OuterPrivateEnvironment]]: outerPrivateEnv, [[Names]]: names }.

# 9.2.1.2 ResolvePrivateIdentifier ( privateEnv, identifier )

The abstract operation ResolvePrivateIdentifier takes arguments privateEnv (a PrivateEnvironment Record) and identifier (a String) and returns a Private Name. It performs the following steps when called:

1. Let names be privateEnv.[[Names]].
2. For each Private Name pn of names, do
   1. If pn.[[Description]] is identifier, then
      1. Return pn.
3. Let outerPrivateEnv be privateEnv.[[OuterPrivateEnvironment]].
4. Assert: outerPrivateEnv is not null.
5. Return ResolvePrivateIdentifier(outerPrivateEnv, identifier).

# 9.3 Realms

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

A realm is represented in this specification as a Realm Record with the fields specified in Table 19:

Table 19: Realm Record Fields

Field Name | Value | Meaning
--- | --- | ---
[[AgentSignifier]] | an agent signifier | The agent that owns this realm
[[Intrinsics]] | a Record whose field names are intrinsic keys and whose values are objects | The intrinsic values used by code associated with this realm
[[GlobalObject]] | an Object | The global object for this realm
[[GlobalEnv]] | a Global Environment Record | The global environment for this realm
[[TemplateMap]] | a List of Records with fields [[Site]] (a TemplateLiteral Parse Node) and [[Array]] (an Array) | 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.
[[LoadedModules]] | a List of LoadedModuleRequest Records | A map from the specifier strings imported by this realm to the resolved Module Record. The list does not contain two different Records r1 and r2 such that ModuleRequestsEqual(r1, r2) is true. Note 2 As mentioned in HostLoadImportedModule (16.2.1.10 Note 1), [[LoadedModules]] in Realm Records is only used when running an `import()` expression in a context where there is no active script or module.
[[HostDefined]] | anything (default value is undefined) | Field reserved for use by hosts that need to associate additional information with a Realm Record.

# 9.3.1 InitializeHostDefinedRealm ( )

The abstract operation InitializeHostDefinedRealm takes no arguments and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

1. Let realm be a new Realm Record.
2. Perform CreateIntrinsics(realm).
3. Set realm.[[AgentSignifier]] to AgentSignifier().
4. Set realm.[[TemplateMap]] to a new empty List.
5. Let newContext be a new execution context.
6. Set the Function of newContext to null.
7. Set the Realm of newContext to realm.
8. Set the ScriptOrModule of newContext to null.
9. Push newContext onto the execution context stack; newContext is now the running execution context.
10. If the host requires use of a specific object to serve as realm's global object, then
    1. Let global be such an object created in a host-defined manner.
11. Else,
    1. Let global be OrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]]).
12. If the host requires that the `this` binding in realm's global scope return an object other than the global object, then
    1. Let thisValue be such an object created in a host-defined manner.
13. Else,
    1. Let thisValue be global.
14. Set realm.[[GlobalObject]] to global.
15. Set realm.[[GlobalEnv]] to NewGlobalEnvironment(global, thisValue).
16. Perform ? SetDefaultGlobalBindings(realm).
17. Create any host-defined global object properties on global.
18. Return unused.

# 9.3.2 CreateIntrinsics ( realmRec )

The abstract operation CreateIntrinsics takes argument realmRec (a Realm Record) and returns unused. It performs the following steps when called:

1. Set realmRec.[[Intrinsics]] to a new Record.
2. Set fields of realmRec.[[Intrinsics]] with the values listed in Table 6. The field names are the names listed in the “Intrinsic Name” column 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, async) 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, prototype is the specified value of the function's [[Prototype]] internal slot, and async is true if the function is described as “async” and false otherwise. The creation of the intrinsics and their properties must be ordered to avoid any dependencies upon objects that have not yet been created.
3. Perform AddRestrictedFunctionProperties(realmRec.[[Intrinsics]].[[%Function.prototype%]], realmRec).
4. Return unused.

# 9.3.3 SetDefaultGlobalBindings ( realmRec )

The abstract operation SetDefaultGlobalBindings takes argument realmRec (a Realm Record) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

1. Let global be realmRec.[[GlobalObject]].
2. For each property of the Global Object specified in clause 19, do
   1. Let name be the String value of the property name.
   2. 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.
   3. Perform ? DefinePropertyOrThrow(global, name, desc).
3. Return unused.

# 9.4 Execution Contexts

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

Table 20: 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.
Function | If this execution context is evaluating the code of a function object, then the value of this component is that function object. If the context is evaluating the code of a Script or Module, the value is null.
Realm | The Realm Record from which associated code accesses ECMAScript resources.
ScriptOrModule | The Module Record or Script Record from which associated code originates. If there is no originating script or module, as is the case for the original execution context created in InitializeHostDefinedRealm, the value is null.

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.

The value of the Realm component of the running execution context is also called the current Realm Record. The value of the Function component of the running execution context is also called the active function object.

ECMAScript code execution contexts have the additional state components listed in Table 21.

Table 21: Additional State Components for ECMAScript Code Execution Contexts

Component | Purpose
--- | ---
LexicalEnvironment | Identifies the Environment Record used to resolve identifier references made by code within this execution context.
VariableEnvironment | Identifies the Environment Record that holds bindings created by VariableStatements within this execution context.
PrivateEnvironment | Identifies the PrivateEnvironment Record that holds Private Names created by ClassElements in the nearest containing class. null if there is no containing class.

The LexicalEnvironment and VariableEnvironment components of an execution context are always Environment Records.

Execution contexts representing the evaluation of Generators have the additional state components listed in Table 22.

Table 22: Additional State Components for Generator Execution Contexts

Component | Purpose
--- | ---
Generator | The Generator that this execution context is evaluating.

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:

1. If the execution context stack is empty, return null.
2. Let ec be the topmost execution context on the execution context stack whose ScriptOrModule component is not null.
3. If no such execution context exists, return null.
4. 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:

1. If env is not present or env is undefined, then
   1. Set env to the running execution context's LexicalEnvironment.
2. Assert: env is an Environment Record.
3. Let strict be IsStrict(the syntactic production that is being evaluated).
4. Return ? GetIdentifierReference(env, name, strict).

Note

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 keyword `this`. It performs the following steps when called:

1. Let env be the running execution context's LexicalEnvironment.
2. Repeat,
   1. Let exists be env.HasThisBinding().
   2. If exists is true, return env.
   3. Let outer be env.[[OuterEnv]].
   4. Assert: outer is not null.
   5. Set env to outer.

Note

The loop in step 2 will always terminate because the list of environments always ends with the global environment which has a `this` binding.

# 9.4.4 ResolveThisBinding ( )

The abstract operation ResolveThisBinding takes no arguments and returns either a normal completion containing an ECMAScript language value or a throw completion. It determines the binding of the keyword `this` using the LexicalEnvironment of the running execution context. It performs the following steps when called:

1. Let envRec be GetThisEnvironment().
2. Return ? envRec.GetThisBinding().

# 9.4.5 GetNewTarget ( )

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:

1. Let envRec be GetThisEnvironment().
2. Assert: envRec has a [[NewTarget]] field.
3. Return envRec.[[NewTarget]].

# 9.4.6 GetGlobalObject ( )

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:

1. Let currentRealm be the current Realm Record.
2. Return currentRealm.[[GlobalObject]].

# 9.5 Jobs and Host Operations to Enqueue Jobs

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 in a particular agent. This specification describes the host hooks HostEnqueueGenericJob, HostEnqueueFinalizationRegistryCleanupJob, HostEnqueuePromiseJob, and HostEnqueueTimeoutJob to schedule jobs. The host hooks in this specification are organized by the additional constraints imposed on the scheduling of jobs. Hosts may define additional abstract operations which schedule jobs. Such operations accept a Job Abstract Closure and a realm (a Realm Record or null) as parameters. If a Realm Record is provided, these operations schedule the job to be performed at some future time in the provided realm, in the agent that owns the realm. If null is provided instead for the realm, then the job does not evaluate ECMAScript code. Their implementations must conform to the following requirements:

- At some future point in time, when there is no running context in the agent for which the job is scheduled and that agent's execution context stack is empty, the implementation must:
  1. Perform any host-defined preparation steps.
  2. Invoke the Job Abstract Closure.
  3. Perform any host-defined cleanup steps, after which the execution context stack must be empty.
- Only one Job may be actively undergoing evaluation at any point in time in an agent.
- Once evaluation of a Job starts, it must run to completion before evaluation of any other Job starts in an agent.
- The Abstract Closure must return a normal completion, implementing its own handling of errors.

Note 1
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:

- GetActiveScriptOrModule() is scriptOrModule.
- If scriptOrModule is a Script Record or Module Record, let ec be the topmost execution context on the execution context stack whose ScriptOrModule component is scriptOrModule. The Realm component of ec is scriptOrModule.[[Realm]].

At any particular time, an execution is prepared to evaluate ECMAScript code if all of the following conditions are true:

- The execution context stack is not empty.
- The Realm component of the topmost execution context on the execution context stack is a Realm Record.

Note 2

Host environments may prepare an execution to evaluate code by pushing execution contexts onto the execution context stack. The specific steps are implementation-defined.

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.

# 9.5.1 JobCallback Records

A JobCallback Record is a Record value used to store a function object and a host-defined value. Function objects that are invoked via a Job enqueued by the host may have additional host-defined context. To propagate the state, Job Abstract Closures should not capture and call function objects directly. Instead, use HostMakeJobCallback and HostCallJobCallback.

Note

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

Table 23: JobCallback Record Fields

Field Name | Value | Meaning
--- | --- | ---
[[Callback]] | a function object | The function to invoke when the Job is invoked.
[[HostDefined]] | anything (default value is empty) | Field reserved for use by hosts.

# 9.5.2 HostMakeJobCallback ( callback )

The host-defined abstract operation HostMakeJobCallback takes argument callback (a function object) and returns a JobCallback Record.

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:

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

# 9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList )

The host-defined abstract operation HostCallJobCallback takes arguments jobCallback (a JobCallback Record), V (an ECMAScript language value), and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or a throw completion.

An implementation of HostCallJobCallback must conform to the following requirements:

- It must perform and return the result of Call(jobCallback.[[Callback]], V, argumentsList).

Note

This requirement means that hosts cannot change the [[Call]] behaviour of function objects defined in this specification.

The default implementation of HostCallJobCallback performs the following steps when called:

1. Assert: IsCallable(jobCallback.[[Callback]]) is true.
2. Return ? Call(jobCallback.[[Callback]], V, argumentsList).

ECMAScript hosts that are not web browsers must use the default implementation of HostCallJobCallback.

# 9.5.4 HostEnqueueGenericJob ( job, realm )

The host-defined abstract operation HostEnqueueGenericJob takes arguments job (a Job Abstract Closure) and realm (a Realm Record) and returns unused. It schedules job in the realm realm in the agent signified by realm.[[AgentSignifier]] to be performed at some future time. The Abstract Closures used with this algorithm are intended to be scheduled without additional constraints, such as priority and ordering.

An implementation of HostEnqueueGenericJob must conform to the requirements in 9.5.

# 9.5.5 HostEnqueuePromiseJob ( job, realm )

The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (a Job Abstract 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:

- If realm is not null, each time job is invoked the implementation must perform implementation-defined steps such that execution is prepared to evaluate ECMAScript code at the time of job's invocation.
- 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 then function 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 Record 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.5.6 HostEnqueueTimeoutJob ( timeoutJob, realm, milliseconds )

The host-defined abstract operation HostEnqueueTimeoutJob takes arguments timeoutJob (a Job Abstract Closure), realm (a Realm Record), and milliseconds (a non-negative finite Number) and returns unused. It schedules timeoutJob in the realm realm in the agent signified by realm.[[AgentSignifier]] to be performed after at least milliseconds milliseconds.

An implementation of HostEnqueueTimeoutJob must conform to the requirements in 9.5.

# 9.6 Agents

An agent comprises a set of ECMAScript execution contexts, an execution context stack, a running execution context, an Agent Record, and an executing thread. Except for the executing thread, the constituents of an agent belong exclusively to that agent.

An agent's executing thread executes algorithmic steps on the agent's execution contexts independently of other agents, except that an executing thread may be used as the executing thread by multiple agents, provided none of the agents sharing the thread have an Agent Record whose [[CanBlock]] field is true.

Note 1

Some web browsers share a single executing thread across multiple unrelated tabs of a browser window, for example.

While an agent's executing thread is executing algorithmic steps, the agent is the surrounding agent for those steps. The steps use the surrounding agent to access the specification-level execution objects held within the agent: the running execution context, the execution context stack, and the Agent Record's fields.

An agent signifier is a globally-unique opaque value used to identify an Agent.

Table 24: Agent Record Fields

Field Name | Value | Meaning
--- | --- | ---
[[LittleEndian]] | a Boolean | 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.
[[CanBlock]] | a Boolean | Determines whether the agent can block or not.
[[Signifier]] | an agent signifier | Uniquely identifies the agent within its agent cluster.
[[IsLockFree1]] | a Boolean | true if atomic operations on one-byte values are lock-free, false otherwise.
[[IsLockFree2]] | a Boolean | true if atomic operations on two-byte values are lock-free, false otherwise.
[[IsLockFree8]] | a Boolean | true if atomic operations on eight-byte values are lock-free, false otherwise.
[[CandidateExecution]] | a candidate execution Record | See the memory model.
[[KeptAlive]] | a List of either Objects or Symbols | Initially a new empty List, representing the list of objects and/or symbols to be kept alive until the end of the current Job
[[ModuleAsyncEvaluationCount]] | an integer | Initially 0, used to assign unique incrementing values to the [[AsyncEvaluationOrder]] field of modules that are asynchronous or have asynchronous dependencies.

The values of [[LittleEndian]], [[Signifier]], [[IsLockFree1]], [[IsLockFree2]], and [[IsLockFree8]] cannot change.

Note 2

The values of [[IsLockFree1]], [[IsLockFree2]], and [[IsLockFree8]] 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.6.1 AgentSignifier ( )

The abstract operation AgentSignifier takes no arguments and returns an agent signifier. It performs the following steps when called:

1. Let AR be the Agent Record of the surrounding agent.
2. Return AR.[[Signifier]].

# 9.6.2 AgentCanSuspend ( )

The abstract operation AgentCanSuspend takes no arguments and returns a Boolean. It performs the following steps when called:

1. Let AR be the Agent Record of the surrounding agent.
2. Return AR.[[CanBlock]].

Note

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.6.3 IncrementModuleAsyncEvaluationCount ( )

The abstract operation IncrementModuleAsyncEvaluationCount takes no arguments and returns an integer. It performs the following steps when called:

1. Let AR be the Agent Record of the surrounding agent.
2. Let count be AR.[[ModuleAsyncEvaluationCount]].
3. Set AR.[[ModuleAsyncEvaluationCount]] to count + 1.
4. Return count.

Note

This value is only used to keep track of the relative evaluation order between pending modules. An implementation may unobservably reset [[ModuleAsyncEvaluationCount]] to 0 whenever there are no pending modules.

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

Every agent belongs to exactly one agent cluster.

Note 2

The agents in a cluster need not all be alive at some particular point in time. If agent A creates another agent B, after which A terminates and B creates agent C, 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]] and [[IsLockFree8]] fields.

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.

Each of the following specification values, and values transitively reachable from them, belong to exactly one agent cluster.

- candidate execution Record
- Shared Data Block
- WaiterList Record

Prior to any evaluation of any ECMAScript code by any agent in a cluster, the [[CandidateExecution]] field of the Agent Record for all agents in the cluster is set to the initial candidate execution. The initial candidate execution is an empty candidate execution whose [[EventsRecords]] field is a List containing, for each agent, an Agent Events Record whose [[AgentSignifier]] field is that agent's agent signifier, and whose [[EventList]] and [[AgentSynchronizesWith]] fields are empty Lists.

Note 6

All agents in an agent cluster share the same candidate execution in its Agent Record's [[CandidateExecution]] field. The candidate execution is a specification mechanism used by the memory model.

Note 7

An agent cluster is a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation.

# 9.8 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 unblocked agent is one that is not blocked.

Implementations must ensure that:

- every unblocked agent with a dedicated executing thread eventually makes forward progress
- in a set of agents that share an executing thread, one agent 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 seq-cst writes eventually become observable to all agents.

# 9.9 Processing Model of WeakRef and FinalizationRegistry Targets

# 9.9.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.
- When an object or symbol which is registered with a FinalizationRegistry becomes unreachable, a call of the FinalizationRegistry's cleanup callback may eventually be made, after synchronous ECMAScript execution completes. The FinalizationRegistry cleanup is performed with the CleanupFinalizationRegistry abstract operation.

Neither of these actions (ClearKeptObjects or CleanupFinalizationRegistry) may interrupt synchronous ECMAScript execution. Because hosts may assemble longer, synchronous ECMAScript execution runs, this specification defers the scheduling of ClearKeptObjects and CleanupFinalizationRegistry to the host environment.

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

1. For each element value of S, do
   1. For each WeakRef ref such that ref.[[WeakRefTarget]] is value, do
      1. Set ref.[[WeakRefTarget]] to empty.
   2. For each FinalizationRegistry fg such that fg.[[Cells]] contains a Record cell such that cell.[[WeakRefTarget]] is value, do
      1. Set cell.[[WeakRefTarget]] to empty.
      2. Optionally, perform HostEnqueueFinalizationRegistryCleanupJob(fg).
   3. For each WeakMap map such that map.[[WeakMapData]] contains a Record r such that r.[[Key]] is value, do
      1. Set r.[[Key]] to empty.
      2. Set r.[[Value]] to empty.
   4. For each WeakSet set such that set.[[WeakSetData]] contains value, do
      1. Replace the element of set.[[WeakSetData]] whose value is value with an element whose value is empty.

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.

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

Note 2

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.

# 9.9.4 Host Hooks

# 9.9.4.1 HostEnqueueFinalizationRegistryCleanupJob ( finalizationRegistry )

The host-defined abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument finalizationRegistry (a FinalizationRegistry) and returns unused.

Let cleanupJob be a new Job Abstract Closure with no parameters that captures finalizationRegistry and performs the following steps when called:

1. Let cleanupResult be Completion(CleanupFinalizationRegistry(finalizationRegistry)).
2. If cleanupResult is an abrupt completion, perform any host-defined steps for reporting the error.
3. Return unused.

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

1. Let agentRecord be the surrounding agent's Agent Record.
2. Set agentRecord.[[KeptAlive]] to a new empty List.
3. Return unused.

# 9.11 AddToKeptObjects ( value )

The abstract operation AddToKeptObjects takes argument value (an Object or a Symbol) and returns unused. It performs the following steps when called:

1. Let agentRecord be the surrounding agent's Agent Record.
2. Append value to agentRecord.[[KeptAlive]].
3. Return unused.

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

# 9.12 CleanupFinalizationRegistry ( finalizationRegistry )

The abstract operation CleanupFinalizationRegistry takes argument finalizationRegistry (a FinalizationRegistry) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

1. Assert: finalizationRegistry has [[Cells]] and [[CleanupCallback]] internal slots.
2. Let callback be finalizationRegistry.[[CleanupCallback]].
3. While finalizationRegistry.[[Cells]] contains a Record cell such that cell.[[WeakRefTarget]] is empty, an implementation may perform the following steps:
   1. Choose any such cell.
   2. Remove cell from finalizationRegistry.[[Cells]].
   3. Perform ? HostCallJobCallback(callback, undefined, « cell.[[HeldValue]] »).
4. Return unused.

# 9.13 CanBeHeldWeakly ( v )

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:

1. If v is an Object, return true.
2. If v is a Symbol and KeyForSymbol(v) is undefined, return true.
3. Return false.

Note

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.