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.

The Environment Record abstract class includes the abstract specification methods defined in Table 19. These abstract methods have distinct concrete algorithms for each of the concrete subclasses.

Table 19: Abstract Methods of Environment Records
Method Purpose
HasBinding(N) Determine if an Environment Record has a binding for the String value N. Return true if it does and false if it does not.
CreateMutableBinding(N, D) Create a new but uninitialized mutable binding in an Environment Record. The String value N is the text of the bound name. If the Boolean argument D is true the binding may be subsequently deleted.
CreateImmutableBinding(N, S) Create a new but uninitialized immutable binding in an Environment Record. The String value N is the text of the bound name. If S is true then attempts to set it after it has been initialized will always throw an exception, regardless of the strict mode setting of operations that reference that binding.
InitializeBinding(N, V) Set the value of an already existing but uninitialized binding in an Environment Record. The String value N is the text of the bound name. V is the value for the binding and is a value of any ECMAScript language type.
SetMutableBinding(N, V, S) Set the value of an already existing mutable binding in an Environment Record. The String value N is the text of the bound name. V is the value for the binding and may be a value of any ECMAScript language type. S is a Boolean flag. If S is true and the binding cannot be set throw a TypeError exception.
GetBindingValue(N, S) Returns the value of an already existing binding from an Environment Record. The String value N is the text of the bound name. S is used to identify references originating in strict mode code or that otherwise require strict mode reference semantics. If S is true and the binding does not exist throw a ReferenceError exception. If the binding exists but is uninitialized a ReferenceError is thrown, regardless of the value of S.
DeleteBinding(N) Delete a binding from an Environment Record. The String value N is the text of the bound name. If a binding for N exists, remove the binding and return true. If the binding exists but cannot be removed return false. If the binding does not exist return true.
HasThisBinding() Determine if an Environment Record establishes a this binding. Return true if it does and false if it does not.
HasSuperBinding() Determine if an Environment Record establishes a super method binding. Return true if it does and false if it does not.
WithBaseObject() If this Environment Record is associated with a with statement, return the with object. Otherwise, return undefined.

9.1.1.1 Declarative Environment Records

Each declarative Environment Record is associated with an ECMAScript program scope containing variable, constant, let, class, module, import, and/or function declarations. A declarative Environment Record binds the set of identifiers defined by the declarations contained within its scope.

The behaviour of the concrete specification methods for declarative Environment Records is defined by the following algorithms.

9.1.1.1.1 HasBinding ( N )

The HasBinding concrete method of a declarative Environment Record envRec takes argument N (a String). 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 the name that is the value of 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). 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 has the value 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 NormalCompletion(empty).

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). 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 has the value 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 NormalCompletion(empty).

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). It is used to set the bound value of the current binding of the identifier whose name is the value of the argument N to the value of argument 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 NormalCompletion(empty).

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). It attempts to change the bound value of the current binding of the identifier whose name is the value of the argument N to the value of argument 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 NormalCompletion(empty).
  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, throw a ReferenceError exception.
  4. Else if the binding for N in envRec is a mutable binding, 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 NormalCompletion(empty).
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). It returns the value of its bound identifier whose name is the value of the argument 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). 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 the name that is the value of 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. 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 HasSuperBinding ( )

The HasSuperBinding concrete method of a declarative Environment Record envRec takes no arguments. 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.10 WithBaseObject ( )

The WithBaseObject concrete method of a declarative Environment Record envRec takes no arguments. 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 has the value 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 20.

Table 20: Additional Fields of Object Environment Records
Field Name Value Meaning
[[BindingObject]] Object The binding object of this Environment Record.
[[IsWithEnvironment]] Boolean Indicates whether this Environment Record is created for a with statement.

The behaviour of the concrete specification methods for object Environment Records is defined by the following algorithms.

9.1.1.2.1 HasBinding ( N )

The HasBinding concrete method of an object Environment Record envRec takes argument N (a String). It determines if its associated binding object has a property whose name is the value of the argument 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, @@unscopables).
  6. If Type(unscopables) is 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). It creates in an Environment Record's associated binding object a property whose name is the String value and initializes it to the value undefined. If D has the value 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. Return ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
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). It is used to set the bound value of the current binding of the identifier whose name is the value of the argument N to the value of argument V. It performs the following steps when called:

  1. Return ? envRec.SetMutableBinding(N, V, false).
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). It attempts to set the value of the Environment Record's associated binding object's property whose name is the value of the argument N to the value of argument 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. Return ? Set(bindingObject, N, V, S).

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). It returns the value of its associated binding object's property whose name is the String value of the argument identifier 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 the value undefined; otherwise 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). 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. 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 HasSuperBinding ( )

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

  1. Return false.
Note

Object Environment Records do not provide a super binding.

9.1.1.2.10 WithBaseObject ( )

The WithBaseObject concrete method of an object Environment Record envRec takes no arguments. It performs the following steps when called:

  1. If envRec.[[IsWithEnvironment]] is true, return envRec.[[BindingObject]].
  2. Otherwise, return undefined.

9.1.1.3 Function Environment Records

A function Environment Record is a declarative Environment Record that is used to represent the top-level scope of a function and, if the function is not an ArrowFunction, provides a this binding. If a function is not an ArrowFunction function and references super, its function Environment Record also contains the state that is used to perform super method invocations from within the function.

Function Environment Records have the additional state fields listed in Table 21.

Table 21: Additional Fields of Function Environment Records
Field Name Value Meaning
[[ThisValue]] Any This is the this value used for this invocation of the function.
[[ThisBindingStatus]] lexical | initialized | uninitialized If the value is lexical, this is an ArrowFunction and does not have a local this value.
[[FunctionObject]] Object The function object whose invocation caused this Environment Record to be created.
[[NewTarget]] Object | 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 19 and share the same specifications for all of those methods except for HasThisBinding and HasSuperBinding. In addition, function Environment Records support the methods listed in Table 22:

Table 22: Additional Methods of Function Environment Records
Method Purpose
BindThisValue(V) Set the [[ThisValue]] and record that it has been initialized.
GetThisBinding() Return the value of this Environment Record's this binding. Throws a ReferenceError if the this binding has not been initialized.
GetSuperBase() Return the object that is the base for super property accesses bound in this Environment Record. The value undefined indicates that super property accesses will produce runtime errors.

The behaviour of the additional concrete specification methods for function Environment Records is defined by the following algorithms:

9.1.1.3.1 BindThisValue ( V )

The BindThisValue concrete method of a function Environment Record envRec takes argument V (an ECMAScript language value). 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 V.

9.1.1.3.2 HasThisBinding ( )

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

  1. If envRec.[[ThisBindingStatus]] is lexical, return false; otherwise, return true.

9.1.1.3.3 HasSuperBinding ( )

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

  1. If envRec.[[ThisBindingStatus]] is lexical, return false.
  2. If envRec.[[FunctionObject]].[[HomeObject]] has the value undefined, return false; otherwise, return true.

9.1.1.3.4 GetThisBinding ( )

The GetThisBinding concrete method of a function Environment Record envRec takes no arguments. 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.5 GetSuperBase ( )

The GetSuperBase concrete method of a function Environment Record envRec takes no arguments. It performs the following steps when called:

  1. Let home be envRec.[[FunctionObject]].[[HomeObject]].
  2. If home has the value undefined, return undefined.
  3. Assert: Type(home) is 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.1.9, 8.1.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 its CreateGlobalVarBinding and CreateGlobalFunctionBinding concrete methods.

Global Environment Records have the additional fields listed in Table 23 and the additional methods listed in Table 24.

Table 23: Additional Fields of Global Environment Records
Field Name Value Meaning
[[ObjectRecord]] 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]] Object The value returned by this in global scope. Hosts may provide any ECMAScript Object value.
[[DeclarativeRecord]] 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.
[[VarNames]] List of String The string names bound by FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, and VariableDeclaration declarations in global code for the associated realm.
Table 24: Additional Methods of Global Environment Records
Method Purpose
GetThisBinding() Return the value of this Environment Record's this binding.
HasVarDeclaration (N) Determines if the argument identifier has a binding in this Environment Record that was created using a VariableDeclaration, FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, or AsyncGeneratorDeclaration.
HasLexicalDeclaration (N) Determines if the argument identifier has a binding in this Environment Record that was created using a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
HasRestrictedGlobalProperty (N) Determines if the argument is the name of a global object property that may not be shadowed by a global lexical binding.
CanDeclareGlobalVar (N) Determines if a corresponding CreateGlobalVarBinding call would succeed if called for the same argument N.
CanDeclareGlobalFunction (N) Determines if a corresponding CreateGlobalFunctionBinding call would succeed if called for the same argument N.
CreateGlobalVarBinding(N, D) Used to create and initialize to undefined a global var binding in the [[ObjectRecord]] component of a global Environment Record. The binding will be a mutable binding. The corresponding global object property will have attribute values appropriate for a var. The String value N is the bound name. If D is true the binding may be deleted. Logically equivalent to CreateMutableBinding followed by a SetMutableBinding but it allows var declarations to receive special treatment.
CreateGlobalFunctionBinding(N, V, D) Create and initialize a global function binding in the [[ObjectRecord]] component of a global Environment Record. The binding will be a mutable binding. The corresponding global object property will have attribute values appropriate for a function. The String value N is the bound name. V is the initialization value. If the Boolean argument D is true the binding may be deleted. Logically equivalent to CreateMutableBinding followed by a SetMutableBinding but it allows function declarations to receive special treatment.

The behaviour of the concrete specification methods for global Environment Records is defined by the following algorithms.

9.1.1.4.1 HasBinding ( N )

The HasBinding concrete method of a global Environment Record envRec takes argument N (a String). 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). 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 has the value 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). 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 has the value 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). It is used to set the bound value of the current binding of the identifier whose name is the value of the argument N to the value of argument 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). It attempts to change the bound value of the current binding of the identifier whose name is the value of the argument N to the value of argument V. If the binding is an immutable binding, a TypeError is thrown if S is true. 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). It returns the value of its bound identifier whose name is the value of the argument 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). 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. Let status be ? ObjRec.DeleteBinding(N).
    2. If status is true, then
      1. Let varNames be envRec.[[VarNames]].
      2. If N is an element of varNames, remove that element from the varNames.
    3. Return status.
  7. Return true.

9.1.1.4.8 HasThisBinding ( )

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

  1. Return true.
Note

Global Environment Records always provide a this binding.

9.1.1.4.9 HasSuperBinding ( )

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

  1. Return false.
Note

Global Environment Records do not provide a super binding.

9.1.1.4.10 WithBaseObject ( )

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

  1. Return undefined.

9.1.1.4.11 GetThisBinding ( )

The GetThisBinding concrete method of a global Environment Record envRec takes no arguments. It performs the following steps when called:

  1. Return envRec.[[GlobalThisValue]].

9.1.1.4.12 HasVarDeclaration ( N )

The HasVarDeclaration concrete method of a global Environment Record envRec takes argument N (a String). It determines if the argument identifier has a binding in this record that was created using a VariableStatement or a FunctionDeclaration. It performs the following steps when called:

  1. Let varDeclaredNames be envRec.[[VarNames]].
  2. If varDeclaredNames contains N, return true.
  3. Return false.

9.1.1.4.13 HasLexicalDeclaration ( N )

The HasLexicalDeclaration concrete method of a global Environment Record envRec takes argument N (a String). It determines if the argument identifier has a binding in this record that was created using a lexical declaration such as a LexicalDeclaration or a ClassDeclaration. It performs the following steps when called:

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

9.1.1.4.14 HasRestrictedGlobalProperty ( N )

The HasRestrictedGlobalProperty concrete method of a global Environment Record envRec takes argument N (a String). 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.15 CanDeclareGlobalVar ( N )

The CanDeclareGlobalVar concrete method of a global Environment Record envRec takes argument N (a String). 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.16 CanDeclareGlobalFunction ( N )

The CanDeclareGlobalFunction concrete method of a global Environment Record envRec takes argument N (a String). 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.17 CreateGlobalVarBinding ( N, D )

The CreateGlobalVarBinding concrete method of a global Environment Record envRec takes arguments N (a String) and D (a Boolean). It creates and initializes a mutable binding in the associated object Environment Record and records the bound name in the associated [[VarNames]] List. If a binding already exists, it is reused and assumed to be initialized. It performs the following steps when called:

  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. Let varDeclaredNames be envRec.[[VarNames]].
  7. If varDeclaredNames does not contain N, then
    1. Append N to varDeclaredNames.
  8. Return NormalCompletion(empty).

9.1.1.4.18 CreateGlobalFunctionBinding ( N, V, D )

The CreateGlobalFunctionBinding concrete method of a global Environment Record envRec takes arguments N (a String), V (an ECMAScript language value), and D (a Boolean). It creates and initializes a mutable binding in the associated object Environment Record and records the bound name in the associated [[VarNames]] List. If a binding already exists, it is 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. Let varDeclaredNames be envRec.[[VarNames]].
  9. If varDeclaredNames does not contain N, then
    1. Append N to varDeclaredNames.
  10. Return NormalCompletion(empty).
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 19 and share the same specifications for all of those methods except for GetBindingValue, DeleteBinding, HasThisBinding and GetThisBinding. In addition, module Environment Records support the methods listed in Table 25:

Table 25: Additional Methods of Module Environment Records
Method Purpose
CreateImportBinding(N, M, N2) Create an immutable indirect binding in a module Environment Record. The String value N is the text of the bound name. M is a Module Record, and N2 is a binding that exists in M's module Environment Record.
GetThisBinding() Return the value of this Environment Record's this binding.

The behaviour of the additional concrete specification methods for module Environment Records are defined by the following algorithms:

9.1.1.5.1 GetBindingValue ( N, S )

The GetBindingValue concrete method of a module Environment Record envRec takes arguments N (a String) and S (a Boolean). It returns the value of its bound identifier whose name is the value of the argument 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 undefined, 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. 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. It performs the following steps when called:

  1. Return undefined.

9.1.1.5.5 CreateImportBinding ( N, M, N2 )

The CreateImportBinding concrete method of a module Environment Record envRec takes arguments N (a String), M (a Module Record), and N2 (a String). It creates a new initialized immutable indirect binding for the name N. A binding must not already exist in this Environment Record for N. N2 is the name of a binding that exists in M's module Environment Record. Accesses to the value of the new binding will indirectly access the bound value of the target binding. It performs the following steps when called:

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

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

  1. If env is the value 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. Else,
    1. Let outer be env.[[OuterEnv]].
    2. Return ? GetIdentifierReference(outer, name, strict).

9.1.2.2 NewDeclarativeEnvironment ( E )

The abstract operation NewDeclarativeEnvironment takes argument E (an 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). 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 and newTarget. It performs the following steps when called:

  1. Assert: F is an ECMAScript function.
  2. Assert: Type(newTarget) is Undefined or Object.
  3. Let env be a new function Environment Record containing no bindings.
  4. Set env.[[FunctionObject]] to F.
  5. If F.[[ThisMode]] is lexical, set env.[[ThisBindingStatus]] to lexical.
  6. Else, set env.[[ThisBindingStatus]] to uninitialized.
  7. Set env.[[NewTarget]] to newTarget.
  8. Set env.[[OuterEnv]] to F.[[Environment]].
  9. Return env.

9.1.2.5 NewGlobalEnvironment ( G, thisValue )

The abstract operation NewGlobalEnvironment takes arguments G and thisValue. It performs the following steps when called:

  1. Let objRec be NewObjectEnvironment(G, false, null).
  2. Let dclRec be a new declarative Environment Record containing no bindings.
  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.[[VarNames]] to a new empty List.
  8. Set env.[[OuterEnv]] to null.
  9. Return env.

9.1.2.6 NewModuleEnvironment ( E )

The abstract operation NewModuleEnvironment takes argument E (an 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 26.

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

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

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

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

9.2.1.2 ResolvePrivateIdentifier ( privEnv, identifier )

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

  1. Let names be privEnv.[[Names]].
  2. If names contains a Private Name whose [[Description]] is identifier, then
    1. Let name be that Private Name.
    2. Return name.
  3. Else,
    1. Let outerPrivEnv be privEnv.[[OuterPrivateEnvironment]].
    2. Assert: outerPrivEnv is not null.
    3. Return ResolvePrivateIdentifier(outerPrivEnv, 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 27:

Table 27: Realm Record Fields
Field Name Value Meaning
[[Intrinsics]] Record whose field names are intrinsic keys and whose values are objects The intrinsic values used by code associated with this realm
[[GlobalObject]] Object The global object for this realm
[[GlobalEnv]] global Environment Record The global environment for this realm
[[TemplateMap]] A List of Record { [[Site]]: Parse Node, [[Array]]: Object }.

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
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.
[[HostDefined]] Any, default value is undefined. Field reserved for use by hosts that need to associate additional information with a Realm Record.

9.3.1 CreateRealm ( )

The abstract operation CreateRealm takes no arguments. It performs the following steps when called:

  1. Let realmRec be a new Realm Record.
  2. Perform CreateIntrinsics(realmRec).
  3. Set realmRec.[[GlobalObject]] to undefined.
  4. Set realmRec.[[GlobalEnv]] to undefined.
  5. Set realmRec.[[TemplateMap]] to a new empty List.
  6. Return realmRec.

9.3.2 CreateIntrinsics ( realmRec )

The abstract operation CreateIntrinsics takes argument realmRec. It performs the following steps when called:

  1. Let intrinsics be a new Record.
  2. Set realmRec.[[Intrinsics]] to intrinsics.
  3. Set fields of intrinsics with the values listed in Table 8. The field names are the names listed in column one of the table. The value of each field is a new object value fully and recursively populated with property values as defined by the specification of each object in clauses 19 through 28. All object property values are newly created object values. All values that are built-in function objects are created by performing CreateBuiltinFunction(steps, length, name, slots, realmRec, prototype) where steps is the definition of that function provided by this specification, name is the initial value of the function's name property, length is the initial value of the function's length property, slots is a list of the names, if any, of the function's specified internal slots, and prototype is the specified value of the function's [[Prototype]] internal slot. The creation of the intrinsics and their properties must be ordered to avoid any dependencies upon objects that have not yet been created.
  4. Perform AddRestrictedFunctionProperties(intrinsics.[[%Function.prototype%]], realmRec).
  5. Return intrinsics.

9.3.3 SetRealmGlobalObject ( realmRec, globalObj, thisValue )

The abstract operation SetRealmGlobalObject takes arguments realmRec, globalObj, and thisValue. It performs the following steps when called:

  1. If globalObj is undefined, then
    1. Let intrinsics be realmRec.[[Intrinsics]].
    2. Set globalObj to ! OrdinaryObjectCreate(intrinsics.[[%Object.prototype%]]).
  2. Assert: Type(globalObj) is Object.
  3. If thisValue is undefined, set thisValue to globalObj.
  4. Set realmRec.[[GlobalObject]] to globalObj.
  5. Let newGlobalEnv be NewGlobalEnvironment(globalObj, thisValue).
  6. Set realmRec.[[GlobalEnv]] to newGlobalEnv.
  7. Return realmRec.

9.3.4 SetDefaultGlobalBindings ( realmRec )

The abstract operation SetDefaultGlobalBindings takes argument realmRec. 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 global.

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

Table 28: 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.

Execution contexts for ECMAScript code have the additional state components listed in Table 29.

Table 29: 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 generator objects have the additional state components listed in Table 30.

Table 30: Additional State Components for Generator Execution Contexts
Component Purpose
Generator The generator object 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. 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. Otherwise, return ec's ScriptOrModule.

9.4.2 ResolveBinding ( name [ , env ] )

The abstract operation ResolveBinding takes argument name (a String) and optional argument env (an Environment Record). 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 if env is undefined, then
    1. Set env to the running execution context's LexicalEnvironment.
  2. Assert: env is an Environment Record.
  3. If the code matching the syntactic production that is being evaluated is contained in strict mode code, let strict be true; else let strict be false.
  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. 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. 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. 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. 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. This specification describes the host hook HostEnqueuePromiseJob to schedule one kind of job; hosts may define additional abstract operations which schedule jobs. Such operations accept a Job Abstract Closure as the parameter and schedule it to be performed at some future time. Their implementations must conform to the following requirements:

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:

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

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

Table 31: JobCallback Record Fields
Field Name Value Meaning
[[Callback]] A function object The function to invoke when the Job is invoked.
[[HostDefined]] Any, 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).

The implementation of HostMakeJobCallback must conform to the following requirements:

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

  1. Assert: IsCallable(callback) is true.
  2. 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).

The implementation of HostCallJobCallback must conform to the following requirements:

  • It must always 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 HostEnqueuePromiseJob ( job, realm )

The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (a Job Abstract Closure) and realm (a Realm Record or null). 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.

The implementation of HostEnqueuePromiseJob must conform to the requirements in 9.5 as well as the following:

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 at the time of the GetFunctionRealm call. When the realm is null, no user ECMAScript code will be evaluated and no new ECMAScript objects (e.g. Error objects) will be created. The WHATWG HTML specification (https://html.spec.whatwg.org/), for example, uses realm to check for the ability to run script and for the entry concept.

9.6 InitializeHostDefinedRealm ( )

The abstract operation InitializeHostDefinedRealm takes no arguments. It performs the following steps when called:

  1. Let realm be CreateRealm().
  2. Let newContext be a new execution context.
  3. Set the Function of newContext to null.
  4. Set the Realm of newContext to realm.
  5. Set the ScriptOrModule of newContext to null.
  6. Push newContext onto the execution context stack; newContext is now the running execution context.
  7. If the host requires use of an exotic object to serve as realm's global object, let global be such an object created in a host-defined manner. Otherwise, let global be undefined, indicating that an ordinary object should be created as the global object.
  8. If the host requires that the this binding in realm's global scope return an object other than the global object, let thisValue be such an object created in a host-defined manner. Otherwise, let thisValue be undefined, indicating that realm's global this binding should be the global object.
  9. Perform SetRealmGlobalObject(realm, global, thisValue).
  10. Let globalObj be ? SetDefaultGlobalBindings(realm).
  11. Create any host-defined global object properties on globalObj.
  12. Return NormalCompletion(empty).

9.7 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 a job 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]] property 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 executes jobs, the agent is the surrounding agent for the code in those jobs. The code uses 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.

Table 32: Agent Record Fields
Field Name Value Meaning
[[LittleEndian]] 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. Once the value has been observed it cannot change.
[[CanBlock]] Boolean Determines whether the agent can block or not.
[[Signifier]] Any globally-unique value Uniquely identifies the agent within its agent cluster.
[[IsLockFree1]] Boolean true if atomic operations on one-byte values are lock-free, false otherwise.
[[IsLockFree2]] Boolean true if atomic operations on two-byte values are lock-free, false otherwise.
[[IsLockFree8]] Boolean true if atomic operations on eight-byte values are lock-free, false otherwise.
[[CandidateExecution]] A candidate execution Record See the memory model.
[[KeptAlive]] List of objects Initially a new empty List, representing the list of objects to be kept alive until the end of the current Job

Once the values of [[Signifier]], [[IsLockFree1]], and [[IsLockFree2]] have been observed by any agent in the agent cluster they cannot change.

Note 2

The values of [[IsLockFree1]] and [[IsLockFree2]] are not necessarily determined by the hardware, but may also reflect implementation choices that can vary over time and between ECMAScript implementations.

There is no [[IsLockFree4]] property: 4-byte atomic operations are always lock-free.

In practice, if an atomic operation is implemented with any type of lock the operation is not lock-free. Lock-free does not imply wait-free: there is no upper bound on how many machine steps may be required to complete a lock-free atomic operation.

That an atomic access of size n is lock-free does not imply anything about the (perceived) atomicity of non-atomic accesses of size n, specifically, non-atomic accesses may still be performed as a sequence of several separate memory accesses. See ReadSharedMemory and WriteSharedMemory for details.

Note 3

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

9.7.1 AgentSignifier ( )

The abstract operation AgentSignifier takes no arguments. It performs the following steps when called:

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

9.7.2 AgentCanSuspend ( )

The abstract operation AgentCanSuspend takes no arguments. 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.8 Agent Clusters

An agent cluster is a maximal set of agents that can communicate by operating on shared memory.

Note 1

Programs within different agents may share memory by unspecified means. At a minimum, the backing memory for SharedArrayBuffer objects 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]] property 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]] property in their respective Agent Records; similarly for the [[IsLockFree2]] property.

All agents within a cluster must have different values for the [[Signifier]] property 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.

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 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.9 Forward Progress

For an agent to make forward progress is for it to perform an evaluation step according to this specification.

An agent becomes blocked when its running execution context waits synchronously and indefinitely for an external event. Only agents whose Agent Record's [[CanBlock]] property 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 SeqCst writes eventually become observable to all agents.

9.10 Processing Model of WeakRef and FinalizationRegistry Objects

9.10.1 Objectives

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

The semantics of WeakRef and FinalizationRegistry objects 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 object. This list is reset when synchronous work is done using the ClearKeptObjects abstract operation.
  • When an object 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.10.2 Liveness

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

Note 1
WeakRef-obliviousness, together with liveness, capture two notions. One, that a WeakRef itself does not keep an object alive. Two, that cycles in liveness does not imply that an object is live. To be concrete, if determining obj's liveness depends on determining the liveness of another WeakRef referent, obj2, obj2's liveness cannot assume obj's liveness, which would be circular reasoning.
Note 2
WeakRef-obliviousness is defined on sets of objects instead of individual objects to account for cycles. If it were defined on individual objects, then an object in a cycle will be considered live even though its Object value is only observed via WeakRefs of other objects in the cycle.
Note 3
Colloquially, we say that an individual object is live if every set of objects containing it is live.

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

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

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

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

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

Note 6
Liveness is the lower bound for guaranteeing which WeakRefs engines must not empty. Liveness as defined here is undecidable. In practice, engines use conservative approximations such as reachability. There is expected to be significant implementation leeway.

9.10.3 Execution

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

  1. For each element obj of S, do
    1. For each WeakRef ref such that ref.[[WeakRefTarget]] is obj, do
      1. Set ref.[[WeakRefTarget]] to empty.
    2. For each FinalizationRegistry fg such that fg.[[Cells]] contains a Record cell such that cell.[[WeakRefTarget]] is obj, 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 obj, do
      1. Set r.[[Key]] to empty.
      2. Set r.[[Value]] to empty.
    4. For each WeakSet set such that set.[[WeakSetData]] contains obj, do
      1. Replace the element of set.[[WeakSetData]] whose value is obj with an element whose value is empty.
Note 1

Together with the definition of liveness, this clause prescribes legal 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.

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

9.10.4 Host Hooks

9.10.4.1 HostEnqueueFinalizationRegistryCleanupJob ( finalizationRegistry )

The abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument finalizationRegistry (a FinalizationRegistry). HostEnqueueFinalizationRegistryCleanupJob is an implementation-defined abstract operation that is expected to call CleanupFinalizationRegistry(finalizationRegistry) at some point in the future, if possible. The host's responsibility is to make this call at a time which does not interrupt synchronous ECMAScript code execution.

9.11 ClearKeptObjects ( )

The abstract operation ClearKeptObjects takes no arguments. 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.

9.12 AddToKeptObjects ( object )

The abstract operation AddToKeptObjects takes argument object (an Object). It performs the following steps when called:

  1. Let agentRecord be the surrounding agent's Agent Record.
  2. Append object to agentRecord.[[KeptAlive]].
Note
When the abstract operation AddToKeptObjects is called with a target object reference, it adds the target to a list that will point strongly at the target until ClearKeptObjects is called.

9.13 CleanupFinalizationRegistry ( finalizationRegistry )

The abstract operation CleanupFinalizationRegistry takes argument finalizationRegistry (a FinalizationRegistry). 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 NormalCompletion(undefined).