9 실행 가능한 코드와 실행 컨텍스트(Executable Code and Execution Contexts)

9.1 Environment Record

Environment Record는 ECMAScript 코드의 렉시컬 중첩 구조를 기반으로 Identifier들을 특정 변수와 함수에 연계(association)하기 위해 사용되는 명세 타입이다. 보통 Environment Record는 FunctionDeclaration, BlockStatement, TryStatementCatch 절과 같은 ECMAScript 코드의 특정 구문 구조와 연관된다. 그러한 코드가 실행될 때마다 그 코드가 생성하는 식별자 바인딩을 기록하기 위해 새로운 Environment Record가 생성된다.

모든 Environment Record는 [[OuterEnv]] 필드를 가지며, 이는 null이거나 바깥(Environment Record) 환경 레코드에 대한 참조이다. 이는 Environment Record 값들의 논리적 중첩을 모델링하는 데 사용된다. (내부) Environment Record의 바깥 참조는 논리적으로 그 내부 Environment Record를 둘러싸는 Environment Record에 대한 참조이다. 바깥 Environment Record 역시 자체의 바깥 Environment Record를 가질 수 있다. 하나의 Environment Record는 여러 내부 Environment Record의 바깥 환경으로 사용될 수 있다. 예를 들어, 어떤 FunctionDeclaration이 두 개의 중첩된 FunctionDeclaration을 포함한다면 각각의 중첩 함수 Environment Record의 바깥 Environment Record는 둘러싼 함수의 현재 평가에 대한 Environment Record가 된다.

Environment Record는 순수히 명세 메커니즘이며 ECMAScript 구현의 특정한 실체(artefact)에 대응할 필요는 없다. ECMAScript 프로그램이 그러한 값을 직접 접근하거나 조작하는 것은 불가능하다.

9.1.1 Environment Record 타입 계층(The Environment Record Type Hierarchy)

Environment Record는 단순한 객체 지향 계층에 존재한다고 생각할 수 있는데, Environment Record 자체가 추상 클래스이고 세 개의 구체 하위 클래스(Declarative Environment Record, Object Environment Record, Global Environment Record)가 있다. Function Environment RecordModule Environment RecordDeclarative Environment Record의 하위 클래스이다.

Environment Record 추상 클래스는 Table 14에 정의된 추상 명세 메서드를 포함한다. 이 추상 메서드들은 각 구체 하위 클래스마다 구별되는 구체 알고리즘을 가진다.

Table 14: Environment Record의 추상 메서드(Abstract Methods of Environment Records)
메서드(Method) 목적(Purpose)
HasBinding(N) Environment Record가 문자열 값 N에 대한 바인딩을 가지는지 결정한다. 있다면 true, 없으면 false를 반환.
CreateMutableBinding(N, D) Environment Record에 새이지만 아직 초기화되지 않은 변경 가능(mutable) 바인딩을 생성한다. 문자열 값 N은 바운드 이름 텍스트다. Boolean 인자 Dtrue이면 해당 바인딩은 이후 삭제될 수 있다.
CreateImmutableBinding(N, S) Environment Record에 새이지만 아직 초기화되지 않은 변경 불가능(immutable) 바인딩을 생성한다. 문자열 값 N은 바운드 이름 텍스트다. Strue이면 초기화 후 설정하려는 모든 시도는 (참조하는 연산의 strict 모드 설정과 무관하게) 항상 예외를 던진다.
InitializeBinding(N, V) Environment Record 내 이미 존재하지만 초기화되지 않은 바인딩의 값을 설정한다. 문자열 값 N은 바운드 이름 텍스트. V는 바인딩에 대한 값이며 임의의 ECMAScript 언어 타입 값이다.
SetMutableBinding(N, V, S) 이미 존재하는 mutable 바인딩의 값을 설정한다. 문자열 값 N은 바운드 이름 텍스트, V는 값, S는 Boolean 플래그. Strue이고 바인딩을 설정할 수 없다면 TypeError 예외를 던진다.
GetBindingValue(N, S) 이미 존재하는 바인딩의 값을 반환한다. 문자열 값 N은 바운드 이름 텍스트. S는 strict 모드 코드에서 기원했거나 strict 모드 참조语 의미를 요구하는지 식별하는 데 사용된다. Strue이고 바인딩이 존재하지 않으면 ReferenceError를 던진다. 바인딩이 존재하지만 초기화되지 않았다면 S 값과 무관하게 ReferenceError를 던진다.
DeleteBinding(N) 바인딩을 삭제한다. 문자열 값 N은 바운드 이름 텍스트. N에 대한 바인딩이 존재하면 제거하고 true 반환. 존재하지만 제거 불가하면 false 반환. 존재하지 않으면 true 반환.
HasThisBinding() Environment Recordthis 바인딩을 설정하는지 결정. 그렇다면 true, 아니면 false.
HasSuperBinding() Environment Recordsuper 메서드 바인딩을 설정하는지 결정. 그렇다면 true, 아니면 false. true이면 해당 Environment RecordFunction Environment Record임을 시사하지만, 그 역은 성립하지 않는다.
WithBaseObject() Environment Recordwith 문과 연관되면 with 객체를 반환. 아니면 undefined 반환.

9.1.1.1 Declarative Environment Record

Declarative Environment Record는 변수, constant, let, class, module, import 그리고/또는 function 선언을 포함하는 ECMAScript 프로그램 스코프와 연관된다. Declarative Environment Record는 그 스코프에 포함된 선언들이 정의한 식별자 집합을 바인딩한다.

9.1.1.1.1 HasBinding ( N )

The HasBinding concrete method of Declarative Environment Record envRec takes argument N (String) and returns Boolean을 담는 normal completion. 인수 식별자가 이 레코드에 의해 바인딩된 식별자 중 하나인지 판정한다. It performs the following steps when called:

  1. envRecN에 대한 바인딩을 가지고 있으면 true 반환.
  2. false 반환.

9.1.1.1.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of Declarative Environment Record envRec takes arguments N (String) and D (Boolean) and returns unused를 담는 normal completion. 초기화되지 않은 이름 N에 대한 새로운 mutable 바인딩을 생성한다. 이미 존재해서는 안 된다. Dtrue이면 삭제 대상 표시. It performs the following steps when called:

  1. 단언: envRec은 이미 N 바인딩을 갖지 않는다.
  2. envRec 안에 N에 대한 초기화되지 않은 mutable 바인딩을 생성하고 Dtrue이면 이후 DeleteBinding 호출로 삭제 가능함을 기록.
  3. unused 반환.

9.1.1.1.3 CreateImmutableBinding ( N, S )

The CreateImmutableBinding concrete method of Declarative Environment Record envRec takes arguments N (String) and S (Boolean) and returns unused를 담는 normal completion. 초기화되지 않은 이름 N에 대한 immutable 바인딩을 생성. 이미 존재해서는 안 된다. Strue이면 strict 바인딩으로 표시. It performs the following steps when called:

  1. 단언: envRec은 이미 N 바인딩을 갖지 않는다.
  2. envRecN immutable 바인딩을 생성하고 초기화되지 않았음을 기록. Strue이면 strict 바인딩임을 기록.
  3. unused 반환.

9.1.1.1.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of Declarative Environment Record envRec takes arguments N (String) and V (ECMAScript 언어 값) and returns unused를 담는 normal completion. 이미 존재하는 식별자 N의 현재 바인딩 값(bound value)을 V로 설정한다. N에 대한 초기화되지 않은 바인딩이 이미 있어야 한다. It performs the following steps when called:

  1. 단언: envRecN에 대한 초기화되지 않은 바인딩을 가져야 한다.
  2. envRec에서 N의 바운드 값을 V로 설정.
  3. Record envRecN 바인딩이 초기화되었음을 기록.
  4. unused 반환.

9.1.1.1.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of Declarative Environment Record envRec takes arguments N (String), V (ECMAScript 언어 값), and S (Boolean) and returns unused 또는 throw completion. 식별자 N의 현재 바인딩 값을 V로 변경 시도. 보통 바인딩은 이미 존재하지만 드물게 없을 수도 있다. 바인딩이 immutable이고 Strue이면 TypeError. It performs the following steps when called:

  1. envRecN 바인딩이 없다면
    1. Strue이면 ReferenceError 예외.
    2. envRec.CreateMutableBinding(N, true) 수행.
    3. envRec.InitializeBinding(N, V) 수행.
    4. unused 반환.
  2. envRec에서 N 바인딩이 strict 바인딩이면 Strue로 설정.
  3. envRec에서 N 바인딩이 아직 초기화되지 않았다면 ReferenceError 예외.
  4. Else if envRec에서 N 바인딩이 mutable이면
    1. 그 값을 V로 변경.
  5. Else
    1. 단언: immutable 바인딩 값을 변경하려는 시도.
    2. Strue이면 TypeError 예외.
  6. unused 반환.
Note

단계 1에서 바인딩이 누락되는 ECMAScript 코드 예:

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

9.1.1.1.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of Declarative Environment Record envRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. 이름이 N인 바인딩된 식별자의 값을 반환. 바인딩이 존재하지만 초기화되지 않았으면 S와 무관하게 ReferenceError. It performs the following steps when called:

  1. 단언: envRecN 바인딩을 가진다.
  2. envRecN 바인딩이 초기화되지 않았다면 ReferenceError 예외.
  3. 현재 envRecN으로 바인딩된 값을 반환.

9.1.1.1.7 DeleteBinding ( N )

The DeleteBinding concrete method of Declarative Environment Record envRec takes argument N (String) and returns Boolean을 담는 normal completion. 삭제 대상으로 명시적으로 지정된 바인딩만 삭제할 수 있다. It performs the following steps when called:

  1. 단언: envRecN 바인딩을 가진다.
  2. envRecN 바인딩이 삭제 불가라면 false 반환.
  3. envRec에서 N 바인딩 제거.
  4. true 반환.

9.1.1.1.8 HasThisBinding ( )

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

  1. false 반환.
Note

일반 Declarative Environment Record(즉 Function Environment RecordModule Environment Record가 아닌 것)는 this 바인딩을 제공하지 않는다.

9.1.1.1.9 HasSuperBinding ( )

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

  1. false 반환.
Note

일반 Declarative Environment Recordsuper 바인딩을 제공하지 않는다.

9.1.1.1.10 WithBaseObject ( )

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

  1. undefined 반환.

9.1.1.2 Object Environment Record

Object Environment Recordbinding object라 불리는 객체와 연관된다. Object Environment Record는 그 binding object의 프로퍼티 이름과 직접 대응하는 문자열 식별자 이름 집합을 바인딩한다. IdentifierName 형태가 아닌 프로퍼티 키는 포함되지 않는다. own 및 상속 프로퍼티 모두 [[Enumerable]] 속성과 무관하게 포함된다. 객체에 프로퍼티가 동적으로 추가/삭제될 수 있으므로 Object Environment Record가 바인딩하는 식별자 집합은 프로퍼티를 추가/삭제하는 어떤 연산의 부수 효과로 잠재적으로 변화할 수 있다. 그러한 부수 효과로 생성된 바인딩은 대응 프로퍼티의 Writable 속성이 false일지라도 mutable 바인딩으로 간주된다. Object Environment Record에는 immutable 바인딩이 존재하지 않는다.

with 문(14.11)에 대해 생성된 Object Environment Record는 함수 호출에서 사용할 암묵적 this 값을 그 binding object로 제공할 수 있다. 이 기능은 Boolean [[IsWithEnvironment]] 필드로 제어된다.

Object Environment Record는 Table 15에 나열된 추가 상태 필드를 가진다.

Table 15: Object Environment Record의 추가 필드(Additional Fields of Object Environment Records)
필드 이름(Field Name) 값(Value) 의미(Meaning)
[[BindingObject]] 객체(Object) Environment Record의 바인딩 객체.
[[IsWithEnvironment]] Boolean Environment Recordwith 문을 위해 생성되었는지 여부.

9.1.1.2.1 HasBinding ( N )

The HasBinding concrete method of Object Environment Record envRec takes argument N (String) and returns Boolean 또는 throw completion. 연관된 binding object가 이름 N인 프로퍼티를 가지는지 판정한다. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. foundBinding을 ? HasProperty(bindingObject, N)로 둔다.
  3. foundBindingfalse이면 false 반환.
  4. envRec.[[IsWithEnvironment]]false이면 true 반환.
  5. unscopables를 ? Get(bindingObject, %Symbol.unscopables%)로 둔다.
  6. unscopables가 Object이면
    1. blockedToBoolean(? Get(unscopables, N))로 둔다.
    2. blockedtrue이면 false 반환.
  7. true 반환.

9.1.1.2.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of Object Environment Record envRec takes arguments N (String) and D (Boolean) and returns unused 또는 throw completion. Environment Record의 binding object에 이름 N 프로퍼티를 생성하고 값을 undefined로 초기화. Dtrue이면 새 프로퍼티 [[Configurable]]true, 아니면 false. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }) 수행.
  3. unused 반환.
Note

보통 envRecN 바인딩을 갖지 않지만 갖고 있다면 DefinePropertyOrThrow 의미론이 기존 바인딩을 교체/섀도우하거나 abrupt completion을 유발할 수 있다.

9.1.1.2.3 CreateImmutableBinding ( N, S )

Object Environment Record의 CreateImmutableBinding 구체 메서드는 이 명세 내에서 사용되지 않는다.

9.1.1.2.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of Object Environment Record envRec takes arguments N (String) and V (ECMAScript 언어 값) and returns unused 또는 throw completion. 이름 N인 바인딩 객체 프로퍼티의 값을 V로 설정. It performs the following steps when called:

  1. envRec.SetMutableBinding(N, V, false) 수행.
  2. unused 반환.
Note

이 명세에서 Object Environment Record에 대한 모든 CreateMutableBinding 사용은 같은 이름에 대한 InitializeBinding 호출로 즉시 이어지므로, 초기화 상태를 명시적으로 추적하지 않는다.

9.1.1.2.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of Object Environment Record envRec takes arguments N (String), V (ECMAScript 언어 값), and S (Boolean) and returns unused 또는 throw completion. 연관된 binding object의 프로퍼티 N 값을 V로 설정 시도. 보통 존재하지만 없거나 쓰기 불가능이면 S에 따라 오류 처리. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. stillExists를 ? HasProperty(bindingObject, N)로 둔다.
  3. stillExistsfalse이고 Strue이면 ReferenceError 예외.
  4. Set(bindingObject, N, V, S) 수행.
  5. unused 반환.

9.1.1.2.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of Object Environment Record envRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. binding object의 이름 N 프로퍼티 값을 반환. 존재하지 않을 경우 S에 따라 결과 결정. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. value를 ? HasProperty(bindingObject, N)로 둔다.
  3. valuefalse이면
    1. Sfalse이면 undefined 반환; 아니면 ReferenceError 예외.
  4. Get(bindingObject, N) 반환.

9.1.1.2.7 DeleteBinding ( N )

The DeleteBinding concrete method of Object Environment Record envRec takes argument N (String) and returns Boolean 또는 throw completion. [[Configurable]]true인 환경 객체 프로퍼티에 대응되는 바인딩만 삭제 가능. It performs the following steps when called:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. bindingObject.[[Delete]](N) 반환.

9.1.1.2.8 HasThisBinding ( )

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

  1. false 반환.
Note

Object Environment Recordthis 바인딩을 제공하지 않는다.

9.1.1.2.9 HasSuperBinding ( )

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

  1. false 반환.
Note

Object Environment Recordsuper 바인딩을 제공하지 않는다.

9.1.1.2.10 WithBaseObject ( )

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

  1. envRec.[[IsWithEnvironment]]true이면 envRec.[[BindingObject]] 반환.
  2. 아니면 undefined 반환.

9.1.1.3 Function Environment Record

Function Environment Record는 함수의 최상위 스코프를 나타내는 Declarative Environment Record이며 함수가 ArrowFunction이 아니면 this 바인딩을 제공한다. 함수가 ArrowFunction이 아니고 super를 참조하는 경우 그 Function Environment Record는 함수 내에서 super 메서드 호출을 수행하는 데 사용되는 상태도 포함한다.

Function Environment Record는 Table 16에 나열된 추가 상태 필드를 가진다.

Table 16: Function Environment Record의 추가 필드(Additional Fields of Function Environment Records)
필드 이름 의미
[[ThisValue]] ECMAScript 언어 값 이 함수 호출에 사용되는 this 값.
[[ThisBindingStatus]] lexical, initialized, 또는 uninitialized 값이 lexical이면 이는 ArrowFunction이며 로컬 this 값이 없다.
[[FunctionObject]] ECMAScript 함수 객체 Environment Record를 생성한 호출의 대상 함수 객체.
[[NewTarget]] 생성자 또는 undefined [[Construct]] 내부 메서드로 생성되었다면 [[Construct]] newTarget 매개변수의 값; 아니면 undefined.

Function Environment Record는 Table 14에 나열된 모든 Declarative Environment Record 메서드를 지원하고 HasThisBinding 및 HasSuperBinding을 제외한 명세는 동일하다. 추가로 Table 17에 나열된 메서드를 지원한다:

Table 17: Function Environment Record의 추가 메서드(Additional Methods of Function Environment Records)
메서드 목적
GetThisBinding() Environment Recordthis 바인딩 값을 반환. 초기화되지 않았으면 ReferenceError.

9.1.1.3.1 BindThisValue ( envRec, V )

The abstract operation BindThisValue takes arguments envRec (Function Environment Record) and V (ECMAScript 언어 값) and returns unused 또는 throw completion. envRec.[[ThisValue]]를 설정하고 초기화되었음을 기록한다. It performs the following steps when called:

  1. 단언: envRec.[[ThisBindingStatus]]lexical이 아니다.
  2. envRec.[[ThisBindingStatus]]initialized이면 ReferenceError 예외.
  3. envRec.[[ThisValue]]V로 설정.
  4. envRec.[[ThisBindingStatus]]initialized로 설정.
  5. unused 반환.

9.1.1.3.2 HasThisBinding ( )

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

  1. envRec.[[ThisBindingStatus]]lexical이면 false, 아니면 true 반환.

9.1.1.3.3 HasSuperBinding ( )

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

  1. envRec.[[ThisBindingStatus]]lexical이면 false 반환.
  2. envRec.[[FunctionObject]].[[HomeObject]]undefined이면 false, 아니면 true 반환.

9.1.1.3.4 GetThisBinding ( )

The GetThisBinding concrete method of Function Environment Record envRec takes no arguments and returns ECMAScript 언어 값 또는 throw completion. It performs the following steps when called:

  1. 단언: envRec.[[ThisBindingStatus]]lexical이 아니다.
  2. envRec.[[ThisBindingStatus]]uninitialized이면 ReferenceError 예외.
  3. envRec.[[ThisValue]] 반환.

9.1.1.3.5 GetSuperBase ( envRec )

The abstract operation GetSuperBase takes argument envRec (Function Environment Record) and returns Object, null, 또는 undefined. envRec에 바인딩된 super 프로퍼티 접근의 기반 객체를 반환한다. undefined 값은 그러한 접근이 런타임 오류를 낼 것임을 나타낸다. It performs the following steps when called:

  1. homeenvRec.[[FunctionObject]].[[HomeObject]]로 둔다.
  2. homeundefined이면 undefined 반환.
  3. 단언: home은 ordinary object.
  4. home.[[GetPrototypeOf]]() 반환.

9.1.1.4 Global Environment Record

Global Environment Record는 공통 realm에서 처리되는 모든 ECMAScript Script 요소가 공유하는 가장 바깥 스코프를 나타낸다. Global Environment Record는 내장(global) 전역(19 절), 전역 객체의 프로퍼티 및 Script 내 모든 최상위 선언(8.2.9, 8.2.11)의 바인딩을 제공한다.

Global Environment Record는 논리적으로 단일 레코드이지만 Object Environment RecordDeclarative Environment Record를 캡슐화한 합성체로 명세된다. Object Environment Record는 관련 Realm Record전역 객체를 기본 객체로 가진다. 이 전역 객체는 Global Environment Record의 GetThisBinding 구체 메서드가 반환하는 값이다. Global Environment Record의 Object Environment Record 구성 요소는 모든 내장 전역(19)과 전역 코드에 포함된 FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, VariableStatement이 도입한 바인딩을 포함한다. 전역 코드의 다른 ECMAScript 선언에 대한 바인딩은 Global Environment Record의 Declarative Environment Record 구성 요소에 들어 있다.

프로퍼티는 전역 객체에 직접 생성될 수 있다. 따라서 Global Environment Record의 Object Environment Record 구성 요소는 선언에 의해 명시적으로 생성된 바인딩과 전역 객체의 프로퍼티로 암묵적으로 생성된 바인딩을 모두 포함할 수 있다. 어느 바인딩이 선언을 통해 명시적으로 생성되었는지 식별하기 위해 Global Environment Record는 CreateGlobalVarBindingCreateGlobalFunctionBinding 추상 연산을 사용해 바인딩된 이름 목록을 유지한다.

Global Environment Record는 Table 18에 나열된 추가 필드와 Table 19에 나열된 추가 메서드를 가진다.

Table 18: Global Environment Record의 추가 필드(Additional Fields of Global Environment Records)
필드 이름 의미
[[ObjectRecord]] Object Environment Record 바인딩 객체는 전역 객체. 관련 realm의 전역 코드 내 FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, VariableDeclaration 바인딩과 전역 내장 바인딩을 포함.
[[GlobalThisValue]] Object 전역 스코프에서 this가 반환하는 값. 호스트는 임의의 ECMAScript Object 값을 제공할 수 있다.
[[DeclarativeRecord]] Declarative Environment Record Contains 전역 코드 선언 중 FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, VariableDeclaration을 제외한 모든 선언 바인딩.
Table 19: Global Environment Record의 추가 메서드(Additional Methods of Global Environment Records)
메서드 목적
GetThisBinding() Environment Recordthis 바인딩 값을 반환.

9.1.1.4.1 HasBinding ( N )

The HasBinding concrete method of Global Environment Record envRec takes argument N (String) and returns Boolean 또는 throw completion. 인수 식별자가 레코드에 의해 바인딩된 식별자 중 하나인지 판정. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true이면 true 반환.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. ObjRec.HasBinding(N) 반환.

9.1.1.4.2 CreateMutableBinding ( N, D )

The CreateMutableBinding concrete method of Global Environment Record envRec takes arguments N (String) and D (Boolean) and returns unused 또는 throw completion. 초기화되지 않은 N mutable 바인딩을 새로 생성. 관련 DeclarativeRecord에 생성. 이미 존재하면 안 됨. Dtrue면 삭제 가능 표시. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true이면 TypeError 예외.
  3. DclRec.CreateMutableBinding(N, D) 반환.

9.1.1.4.3 CreateImmutableBinding ( N, S )

The CreateImmutableBinding concrete method of Global Environment Record envRec takes arguments N (String) and S (Boolean) and returns unused 또는 throw completion. 초기화되지 않은 N immutable 바인딩 생성. 이미 존재하면 안 됨. Strue이면 strict 바인딩. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true이면 TypeError 예외.
  3. DclRec.CreateImmutableBinding(N, S) 반환.

9.1.1.4.4 InitializeBinding ( N, V )

The InitializeBinding concrete method of Global Environment Record envRec takes arguments N (String) and V (ECMAScript 언어 값) and returns unused 또는 throw completion. 식별자 N의 현재 바인딩 값을 V로 설정. N에 대한 초기화되지 않은 바인딩이 이미 존재해야 한다. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true이면
    1. DclRec.InitializeBinding(N, V) 반환.
  3. 단언: 바인딩이 존재한다면 Object Environment Record에 있다.
  4. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  5. ObjRec.InitializeBinding(N, V) 반환.

9.1.1.4.5 SetMutableBinding ( N, V, S )

The SetMutableBinding concrete method of Global Environment Record envRec takes arguments N (String), V (ECMAScript 언어 값), and S (Boolean) and returns unused 또는 throw completion. 식별자 N의 현재 바인딩 값을 V로 변경 시도. immutable 바인딩이고 Strue이면 TypeError. 프로퍼티 N은 보통 존재하지만 없거나 현재 writable이 아닐 수도 있으며 이는 S에 따라 처리. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true이면
    1. DclRec.SetMutableBinding(N, V, S) 반환.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. ObjRec.SetMutableBinding(N, V, S) 반환.

9.1.1.4.6 GetBindingValue ( N, S )

The GetBindingValue concrete method of Global Environment Record envRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. 식별자 N의 값을 반환. 바인딩이 초기화되지 않았으면 ReferenceError. 프로퍼티 N은 보통 존재하지만 없거나 writable이 아닐 수도 있는데 이는 S에 따라 처리. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true이면
    1. DclRec.GetBindingValue(N, S) 반환.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. ObjRec.GetBindingValue(N, S) 반환.

9.1.1.4.7 DeleteBinding ( N )

The DeleteBinding concrete method of Global Environment Record envRec takes argument N (String) and returns Boolean 또는 throw completion. 삭제 대상으로 명시된 바인딩만 삭제 가능. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true이면
    1. DclRec.DeleteBinding(N) 반환.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. globalObjectObjRec.[[BindingObject]]로 둔다.
  5. existingProp을 ? HasOwnProperty(globalObject, N)로 둔다.
  6. existingProptrue이면
    1. ObjRec.DeleteBinding(N) 반환.
  7. true 반환.

9.1.1.4.8 HasThisBinding ( )

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

  1. true 반환.
Note

Global Environment Record는 항상 this 바인딩을 제공한다.

9.1.1.4.9 HasSuperBinding ( )

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

  1. false 반환.
Note

Global Environment Recordsuper 바인딩을 제공하지 않는다.

9.1.1.4.10 WithBaseObject ( )

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

  1. undefined 반환.

9.1.1.4.11 GetThisBinding ( )

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

  1. envRec.[[GlobalThisValue]] 반환.

9.1.1.4.12 HasLexicalDeclaration ( envRec, N )

The abstract operation HasLexicalDeclaration takes arguments envRec (Global Environment Record) and N (String) and returns Boolean. 인수 식별자가 envRec에서 LexicalDeclaration 또는 ClassDeclaration 같은 렉시컬 선언을 사용해 생성된 바인딩을 가지는지 판정. It performs the following steps when called:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N) 반환.

9.1.1.4.13 HasRestrictedGlobalProperty ( envRec, N )

The abstract operation HasRestrictedGlobalProperty takes arguments envRec (Global Environment Record) and N (String) and returns Boolean 또는 throw completion. 인수 식별자가 전역 객체의, 전역 렉시컬 바인딩으로 섀도우 되어서는 안 되는 프로퍼티 이름인지 판정. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. existingProp을 ? globalObject.[[GetOwnProperty]](N)로 둔다.
  4. existingPropundefined이면 false 반환.
  5. existingProp.[[Configurable]]true이면 false 반환.
  6. true 반환.
Note

프로퍼티는 var나 function 선언 대신 직접 전역 객체에 존재할 수도 있다. 글로벌 렉시컬 바인딩은 전역 객체의 non-configurable 프로퍼티와 같은 이름으로 생성될 수 없다. "undefined" 전역 프로퍼티가 예.

9.1.1.4.14 CanDeclareGlobalVar ( envRec, N )

The abstract operation CanDeclareGlobalVar takes arguments envRec (Global Environment Record) and N (String) and returns Boolean 또는 throw completion. 같은 N으로 CreateGlobalVarBinding 호출이 성공할지 여부 결정. 중복 var 선언 및 기존 전역 객체 프로퍼티에 대한 var 선언 허용. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. hasProperty를 ? HasOwnProperty(globalObject, N)로 둔다.
  4. hasPropertytrue이면 true 반환.
  5. IsExtensible(globalObject) 반환.

9.1.1.4.15 CanDeclareGlobalFunction ( envRec, N )

The abstract operation CanDeclareGlobalFunction takes arguments envRec (Global Environment Record) and N (String) and returns Boolean 또는 throw completion. 같은 N으로 CreateGlobalFunctionBinding 호출이 성공할지 여부 결정. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. existingProp을 ? globalObject.[[GetOwnProperty]](N)로 둔다.
  4. existingPropundefined이면 ? IsExtensible(globalObject) 반환.
  5. existingProp.[[Configurable]]true이면 true 반환.
  6. IsDataDescriptor(existingProp)가 true이고 existingProp 속성 값이 { [[Writable]]: true, [[Enumerable]]: true }이면 true 반환.
  7. false 반환.

9.1.1.4.16 CreateGlobalVarBinding ( envRec, N, D )

The abstract operation CreateGlobalVarBinding takes arguments envRec (Global Environment Record), N (String), and D (Boolean) and returns unused 또는 throw completion. 연관된 Object Environment Record에 mutable 바인딩을 생성·초기화. 이미 존재하면 재사용되고 초기화된 것으로 간주. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. hasProperty를 ? HasOwnProperty(globalObject, N)로 둔다.
  4. extensible을 ? IsExtensible(globalObject)로 둔다.
  5. hasPropertyfalse이고 extensibletrue이면
    1. ObjRec.CreateMutableBinding(N, D) 수행.
    2. ObjRec.InitializeBinding(N, undefined) 수행.
  6. unused 반환.

9.1.1.4.17 CreateGlobalFunctionBinding ( envRec, N, V, D )

The abstract operation CreateGlobalFunctionBinding takes arguments envRec (Global Environment Record), N (String), V (ECMAScript 언어 값), and D (Boolean) and returns unused 또는 throw completion. 연관된 Object Environment Record에 mutable 바인딩을 생성·초기화. 이미 존재하면 대체. It performs the following steps when called:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. existingProp을 ? globalObject.[[GetOwnProperty]](N)로 둔다.
  4. existingPropundefined이거나 existingProp.[[Configurable]]true이면
    1. desc를 PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }로 둔다.
  5. Else
    1. desc를 PropertyDescriptor { [[Value]]: V }로 둔다.
  6. DefinePropertyOrThrow(globalObject, N, desc) 수행.
  7. Set(globalObject, N, V, false) 수행.
  8. unused 반환.
Note

전역 함수 선언은 항상 전역 객체의 own 프로퍼티로 표현된다. 가능하면 기존 own 프로퍼티가 표준 속성 집합으로 재구성된다. 단계 7은 InitializeBinding 구체 메서드 호출과 동등하며 globalObject가 Proxy이면 동일한 Proxy 트랩 호출 순서를 만든다.

9.1.1.5 Module Environment Record

Module Environment Record는 ECMAScript Module의 바깥 스코프를 나타내는 Declarative Environment Record이며, 일반 mutable/immutable 바인딩 외에 다른 Environment Record에 존재하는 대상 바인딩에 간접 접근을 제공하는 immutable import 바인딩도 제공한다.

Module Environment Record는 Table 14에 나열된 모든 Declarative Environment Record 메서드를 지원하며 GetBindingValue, DeleteBinding, HasThisBinding, GetThisBinding을 제외하고 동일한 명세를 공유한다. 추가로 Table 20에 나열된 메서드를 지원한다:

Table 20: Module Environment Record의 추가 메서드(Additional Methods of Module Environment Records)
메서드 목적
GetThisBinding() Environment Recordthis 바인딩 값을 반환.

9.1.1.5.1 GetBindingValue ( N, S )

The GetBindingValue concrete method of Module Environment Record envRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. 이름 N인 바인딩된 식별자 값을 반환. 간접 바인딩이면 대상 바인딩 값을 반환. 바인딩이 존재하지만 초기화되지 않았으면 ReferenceError. It performs the following steps when called:

  1. 단언: Strue.
  2. 단언: envRecN 바인딩을 가진다.
  3. N에 대한 바인딩이 간접 바인딩이면
    1. N 바인딩 생성 시 제공된 간접 값 M, N2를 둔다.
    2. targetEnvM.[[Environment]]로 둔다.
    3. targetEnvempty이면 ReferenceError 예외.
    4. targetEnv.GetBindingValue(N2, true) 반환.
  4. envRecN 바인딩이 초기화되지 않았으면 ReferenceError 예외.
  5. 현재 envRecN으로 바인딩된 값을 반환.
Note

S는 항상 true인데 Module은 항상 strict 모드 코드이기 때문이다.

9.1.1.5.2 DeleteBinding ( N )

Module Environment Record의 DeleteBinding 구체 메서드는 이 명세 내에서 사용되지 않는다.

Note

Module Environment Record는 strict 코드 내에서만 사용되고 초기 에러 규칙이 strict 코드에서 delete 연산자가 Module Environment Record 바인딩으로 해석될 Reference Record에 적용되는 것을 방지한다. 13.5.1.1 참조.

9.1.1.5.3 HasThisBinding ( )

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

  1. true 반환.
Note

Module Environment Record는 항상 this 바인딩을 제공한다.

9.1.1.5.4 GetThisBinding ( )

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

  1. undefined 반환.

9.1.1.5.5 CreateImportBinding ( envRec, N, M, N2 )

The abstract operation CreateImportBinding takes arguments envRec (Module Environment Record), N (String), M (Module Record), and N2 (String) and returns unused. 이름 N에 대한 새로 초기화된 immutable 간접 바인딩을 생성. envRecN 바인딩이 이미 존재해서는 안 됨. N2MModule Environment Record에 존재하는 바인딩 이름. 새 바인딩의 값 접근은 대상 바인딩 값을 간접적으로 접근. It performs the following steps when called:

  1. 단언: envRec은 이미 N 바인딩을 갖지 않는다.
  2. 단언: M.[[Environment]]가 인스턴스화될 때 N2에 대한 direct 바인딩을 가진다.
  3. envRecN immutable 간접 바인딩을 생성하여 M, N2를 대상 바인딩으로 참조하고 초기화되었음을 기록.
  4. unused 반환.

9.1.2 Environment Record 연산(Environment Record Operations)

다음 추상 연산들은 명세에서 Environment Record를 조작하기 위해 사용된다:

9.1.2.1 GetIdentifierReference ( env, name, strict )

The abstract operation GetIdentifierReference takes arguments env (Environment Record 또는 null), name (String), and strict (Boolean) and returns Reference Record 또는 throw completion. It performs the following steps when called:

  1. envnull이면
    1. Reference Record { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty } 반환.
  2. exists를 ? env.HasBinding(name)로 둔다.
  3. existstrue이면
    1. Reference Record { [[Base]]: env, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty } 반환.
  4. Else
    1. outerenv.[[OuterEnv]]로 둔다.
    2. GetIdentifierReference(outer, name, strict) 반환.

9.1.2.2 NewDeclarativeEnvironment ( E )

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

  1. 바인딩이 없는 새 Declarative Environment Record env를 만든다.
  2. env.[[OuterEnv]]E로 설정.
  3. env 반환.

9.1.2.3 NewObjectEnvironment ( O, W, E )

The abstract operation NewObjectEnvironment takes arguments O (Object), W (Boolean), and E (Environment Record 또는 null) and returns Object Environment Record. It performs the following steps when called:

  1. Object Environment Record env 생성.
  2. env.[[BindingObject]]O로 설정.
  3. env.[[IsWithEnvironment]]W로 설정.
  4. env.[[OuterEnv]]E로 설정.
  5. env 반환.

9.1.2.4 NewFunctionEnvironment ( F, newTarget )

The abstract operation NewFunctionEnvironment takes arguments F (ECMAScript 함수 객체) and newTarget (Object 또는 undefined) and returns Function Environment Record. It performs the following steps when called:

  1. 바인딩이 없는 새 Function Environment Record env 생성.
  2. env.[[FunctionObject]]F로 설정.
  3. F.[[ThisMode]]lexical이면 env.[[ThisBindingStatus]]lexical로 설정.
  4. Else env.[[ThisBindingStatus]]uninitialized로 설정.
  5. env.[[NewTarget]]newTarget으로 설정.
  6. env.[[OuterEnv]]F.[[Environment]]로 설정.
  7. env 반환.

9.1.2.5 NewGlobalEnvironment ( G, thisValue )

The abstract operation NewGlobalEnvironment takes arguments G (Object) and thisValue (Object) and returns Global Environment Record. It performs the following steps when called:

  1. objRecNewObjectEnvironment(G, false, null)로 둔다.
  2. dclRecNewDeclarativeEnvironment(null)로 둔다.
  3. Global Environment Record env 생성.
  4. env.[[ObjectRecord]]objRec로 설정.
  5. env.[[GlobalThisValue]]thisValue로 설정.
  6. env.[[DeclarativeRecord]]dclRec로 설정.
  7. env.[[OuterEnv]]null로 설정.
  8. env 반환.

9.1.2.6 NewModuleEnvironment ( E )

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

  1. 바인딩이 없는 새 Module Environment Record env 생성.
  2. env.[[OuterEnv]]E로 설정.
  3. env 반환.

9.2 PrivateEnvironment 레코드(PrivateEnvironment Records)

PrivateEnvironment Record는 ECMAScript 코드에서 ClassDeclarationClassExpression의 렉시컬 중첩 구조를 기반으로 Private Name들을 추적하기 위해 사용되는 명세 메커니즘이다. 이는 Environment Record와 유사하지만 별개의 것이다. 각 PrivateEnvironment Record는 하나의 ClassDeclaration 또는 ClassExpression에 연결된다. 그러한 클래스가 평가될 때마다, 그 클래스가 선언한 Private Name들을 기록하기 위해 새로운 PrivateEnvironment Record가 생성된다.

PrivateEnvironment RecordTable 21에 정의된 필드들을 가진다.

Table 21: PrivateEnvironment Record 필드(PrivateEnvironment Record Fields)
필드 이름(Field Name) 값 타입(Value Type) 의미(Meaning)
[[OuterPrivateEnvironment]] PrivateEnvironment Record 또는 null 가장 가까운 둘러싸는 클래스의 PrivateEnvironment Record. 이 PrivateEnvironment Record가 연결된 클래스가 다른 어떤 클래스에도 포함되지 않았다면 null.
[[Names]] Private Name들의 List 이 클래스가 선언한 Private Name들.

9.2.1 PrivateEnvironment Record 연산(PrivateEnvironment Record Operations)

다음 추상 연산들은 이 명세에서 PrivateEnvironment Record에 대해 동작하기 위해 사용된다:

9.2.1.1 NewPrivateEnvironment ( outerPrivateEnv )

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

  1. names를 새 빈 List로 둔다.
  2. PrivateEnvironment Record { [[OuterPrivateEnvironment]]: outerPrivateEnv, [[Names]]: names } 를 반환한다.

9.2.1.2 ResolvePrivateIdentifier ( privateEnv, identifier )

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

  1. namesprivateEnv.[[Names]]로 둔다.
  2. names의 각 Private Name pn에 대해
    1. pn.[[Description]]identifier이면
      1. pn을 반환한다.
  3. outerPrivateEnvprivateEnv.[[OuterPrivateEnvironment]]로 둔다.
  4. 단언: outerPrivateEnvnull이 아니다.
  5. ResolvePrivateIdentifier(outerPrivateEnv, identifier)를 반환한다.

9.3 Realm들(Realms)

평가되기 전에 모든 ECMAScript 코드는 하나의 realm과 연계되어야 한다. 개념적으로 realm은 일련의 intrinsic 객체, ECMAScript 전역 환경, 그 전역 환경의 범위 내에서 로드된 모든 ECMAScript 코드, 그리고 기타 관련 상태 및 자원으로 구성된다.

realm은 이 명세에서 Table 22에 지정된 필드를 가진 Realm Record로 표현된다:

Table 22: Realm Record 필드(Realm Record Fields)
필드 이름(Field Name) 값(Value) 의미(Meaning)
[[AgentSignifier]] 에이전트 식별자(agent signifier) realm을 소유하는 에이전트
[[Intrinsics]] 필드 이름이 intrinsic key이고 값이 객체인 Record realm에 연계된 코드가 사용하는 intrinsic 값들
[[GlobalObject]] Object realm전역 객체
[[GlobalEnv]] Global Environment Record realm의 전역 환경
[[TemplateMap]] 필드 [[Site]] (TemplateLiteral Parse Node) 및 [[Array]] (Array)를 갖는 Record들의 List

템플릿 객체들은 각 realm별로 그 Realm Record[[TemplateMap]]을 사용하여 정규화(canonicalize)된다. 각 [[Site]] 값은 TemplateLiteral 인 Parse Node이다. 연계된 [[Array]] 값은 태그 함수에 전달되는 해당 템플릿 객체이다.

Note 1
어떤 Parse Node가 도달 불가능(unreachable)이 되면, 대응하는 [[Array]] 또한 도달 불가능해지며, 구현이 그 쌍을 [[TemplateMap]] 리스트에서 제거하더라도 관측 불가능하다.
[[LoadedModules]] LoadedModuleRequest Record들의 List

realm이 import한 명세자(specifier) 문자열에서 해석된 Module Record로의 매핑. 리스트에는 ModuleRequestsEqual(r1, r2)가 true인 서로 다른 Record r1, r2 두 개가 존재하지 않는다.

Note 2
HostLoadImportedModule (16.2.1.10 Note 1)에서 언급했듯이, Realm Record[[LoadedModules]]는 활성 스크립트나 모듈이 없는 문맥에서 import() 표현식을 실행할 때만 사용된다.
[[HostDefined]] 임의(anything) (undefined가 기본값) 호스트Realm Record와 추가 정보를 연계할 필요가 있을 때 사용하기 위한 예약 필드.

9.3.1 InitializeHostDefinedRealm ( )

The abstract operation InitializeHostDefinedRealm takes no arguments and returns unused를 담는 normal completion 또는 throw completion. It performs the following steps when called:

  1. realm을 새로운 Realm Record로 둔다.
  2. CreateIntrinsics(realm)를 수행한다.
  3. realm.[[AgentSignifier]]AgentSignifier()로 설정한다.
  4. realm.[[TemplateMap]]을 새 빈 List로 설정한다.
  5. newContext를 새 실행 컨텍스트로 둔다.
  6. newContext의 Function을 null로 설정한다.
  7. newContextRealmrealm으로 설정한다.
  8. newContext의 ScriptOrModule을 null로 설정한다.
  9. 실행 컨텍스트 스택에 newContext를 push한다; 이제 newContext가 실행 중(running) 실행 컨텍스트다.
  10. 호스트realm전역 객체로서 익조틱(exotic) 객체 사용을 요구한다면
    1. global호스트 정의 방식으로 생성된 그러한 객체로 둔다.
  11. Else,
    1. globalOrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]])로 둔다.
  12. 호스트realm 전역 스코프의 this 바인딩이 전역 객체와 다른 객체를 반환하도록 요구한다면
    1. thisValue호스트 정의 방식으로 생성된 그러한 객체로 둔다.
  13. Else,
    1. thisValueglobal로 둔다.
  14. realm.[[GlobalObject]]global로 설정한다.
  15. realm.[[GlobalEnv]]NewGlobalEnvironment(global, thisValue)로 설정한다.
  16. SetDefaultGlobalBindings(realm)를 수행한다.
  17. 호스트 정의 전역 객체 프로퍼티들을 global에 생성한다.
  18. unused를 반환한다.

9.3.2 CreateIntrinsics ( realmRec )

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

  1. realmRec.[[Intrinsics]]를 새 Record로 설정한다.
  2. realmRec.[[Intrinsics]]의 필드들을 Table 6에 나열된 값으로 설정한다. 필드 이름은 테이블 첫 번째 열의 이름들이다. 각 필드 값은 19부터 28까지의 각 객체 명세에 따라 그 프로퍼티 값으로 완전하고 재귀적으로 채워진 새 객체 값이다. 모든 객체 프로퍼티 값은 새로 생성된 객체 값이다. 내장 함수 객체인 모든 값은 CreateBuiltinFunction(steps, length, name, slots, realmRec, prototype)을 수행하여 생성되는데, 여기서 steps는 이 명세가 제공하는 그 함수의 정의, name은 함수의 초기 "name" 프로퍼티 값, length는 함수의 초기 "length" 프로퍼티 값, slots는 (있다면) 함수의 지정된 내부 슬롯 이름들의 리스트, prototype은 함수 [[Prototype]] 내부 슬롯의 지정된 값이다. intrinsic과 그 프로퍼티 생성은 아직 생성되지 않은 객체에 대한 의존성이 없도록 순서가 정해져야 한다.
  3. AddRestrictedFunctionProperties(realmRec.[[Intrinsics]].[[%Function.prototype%]], realmRec)를 수행한다.
  4. unused를 반환한다.

9.3.3 SetDefaultGlobalBindings ( realmRec )

The abstract operation SetDefaultGlobalBindings takes argument realmRec (Realm Record) and returns unused를 담는 normal completion 또는 throw completion. It performs the following steps when called:

  1. globalrealmRec.[[GlobalObject]]로 둔다.
  2. 19 절에 지정된 전역 객체의 각 프로퍼티에 대해
    1. name을 그 프로퍼티 이름의 String 값으로 둔다.
    2. desc를 그 프로퍼티에 대해 지정된 속성들을 포함하는 완전히 채워진 데이터 프로퍼티 디스크립터로 둔다. 19.2, 19.3, 또는 19.4에 나열된 프로퍼티의 경우 [[Value]] 속성 값은 realmRec의 해당 intrinsic 객체이다.
    3. DefinePropertyOrThrow(global, name, desc)를 수행한다.
  3. unused를 반환한다.

9.4 실행 컨텍스트들(Execution Contexts)

execution context는 ECMAScript 구현이 코드의 런타임 평가를 추적하기 위해 사용하는 명세 장치이다. 어느 시점에도 코드 실행 중인 에이전트당 실제로 코드를 실행하는 실행 컨텍스트는 최대 하나이다. 이는 그 에이전트의 running execution context로 알려져 있다. 이 명세에서 running execution context에 대한 모든 언급은 둘러싼 에이전트의 running execution context를 가리킨다.

execution context stack은 실행 컨텍스트들을 추적하는 데 사용된다. running execution context는 항상 이 스택의 최상단 요소이다. 현재 running execution context에 연계된 실행 가능한 코드로부터 그 실행 컨텍스트와 연계되지 않은 실행 가능한 코드로 제어가 이전될 때마다 새로운 실행 컨텍스트가 생성된다. 새로 생성된 실행 컨텍스트는 스택에 push되며 running execution context가 된다.

실행 컨텍스트는 그 연계된 코드의 실행 진행을 추적하는 데 필요한 구현별 상태를 포함한다. 각 실행 컨텍스트는 최소한 Table 23에 나열된 상태 구성 요소들을 가진다.

Table 23: 모든 실행 컨텍스트의 상태 구성 요소(State Components for All Execution Contexts)
구성 요소(Component) 목적(Purpose)
code evaluation state 이 실행 컨텍스트와 연계된 코드의 평가 수행, 일시중단, 재개에 필요한 모든 상태.
Function 이 실행 컨텍스트가 함수 객체의 코드를 평가 중이면 이 구성 요소 값은 그 함수 객체이고, Script 또는 Module의 코드를 평가 중이면 값은 null.
Realm 연계된 코드가 ECMAScript 자원에 접근하는 데 사용하는 Realm Record.
ScriptOrModule 연계된 코드가 기원한 Module Record 또는 Script Record. 원래 실행 컨텍스트(InitializeHostDefinedRealm에서 생성된)처럼 기원 스크립트나 모듈이 없는 경우 값은 null.

running execution context에 의한 코드 평가는 이 명세에 정의된 여러 지점에서 일시중단(suspend)될 수 있다. 한 번 running execution context가 일시중단되면, 다른 실행 컨텍스트가 running execution context가 되어 자신의 코드를 평가하기 시작할 수 있다. 이후 어느 시점에 일시중단된 실행 컨텍스트가 다시 running execution context가 되어 이전에 일시중단된 지점부터 자신의 코드를 계속 평가할 수 있다. running execution context 상태의 전환은 보통 스택과 같은 후입선출(LIFO) 방식으로 발생하지만, 일부 ECMAScript 기능은 비 LIFO 전환을 요구한다.

running execution contextRealm 구성 요소 값은 current Realm Record라고도 한다. running execution context의 Function 구성 요소 값은 active function object라고도 한다.

ECMAScript 코드 실행 컨텍스트Table 24에 나열된 추가 상태 구성 요소를 가진다.

Table 24: ECMAScript 코드 실행 컨텍스트의 추가 상태 구성 요소(Additional State Components for ECMAScript Code Execution Contexts)
구성 요소(Component) 목적(Purpose)
LexicalEnvironment 이 실행 컨텍스트 내 코드가 수행하는 식별자 참조를 해석하는 데 사용되는 Environment Record를 식별.
VariableEnvironment 이 실행 컨텍스트 내 VariableStatement에 의해 생성된 바인딩을 보유하는 Environment Record를 식별.
PrivateEnvironment 가장 가까운 둘러싸는 클래스의 ClassElement들이 생성한 Private Name들을 보유하는 PrivateEnvironment Record를 식별. 둘러싸는 클래스가 없으면 null.

실행 컨텍스트의 LexicalEnvironment 및 VariableEnvironment 구성 요소는 항상 Environment Record이다.

Generator 평가를 나타내는 실행 컨텍스트는 Table 25에 나열된 추가 상태 구성 요소를 가진다.

Table 25: Generator 실행 컨텍스트의 추가 상태 구성 요소(Additional State Components for Generator Execution Contexts)
구성 요소(Component) 목적(Purpose)
Generator 이 실행 컨텍스트가 평가 중인 Generator.

대부분의 상황에서 이 명세의 알고리즘이 직접 조작하는 것은 running execution context(실행 컨텍스트 스택의 최상단)이다. 따라서 “LexicalEnvironment”, “VariableEnvironment”라는 용어가 한정 없이 사용될 때 그것들은 running execution context의 해당 구성 요소를 의미한다.

실행 컨텍스트는 순수한 명세 메커니즘이며 ECMAScript 구현의 특정한 실체에 대응할 필요가 없다. ECMAScript 코드는 실행 컨텍스트를 직접 접근하거나 관찰할 수 없다.

9.4.1 GetActiveScriptOrModule ( )

The abstract operation GetActiveScriptOrModule takes no arguments and returns Script Record, Module Record, 또는 null. running execution context를 기반으로 실행 중인 스크립트 또는 모듈을 결정하는 데 사용된다. It performs the following steps when called:

  1. 실행 컨텍스트 스택이 비어 있으면 null을 반환한다.
  2. ec를 실행 컨텍스트 스택의 최상단에서 ScriptOrModule 구성 요소가 null이 아닌 실행 컨텍스트로 둔다.
  3. 그러한 실행 컨텍스트가 없으면 null을 반환하고; 그렇지 않으면 ec의 ScriptOrModule을 반환한다.

9.4.2 ResolveBinding ( name [ , env ] )

The abstract operation ResolveBinding takes argument name (String) and optional argument env (Environment Record 또는 undefined) and returns Reference Record를 담는 normal completion 또는 throw completion. name의 바인딩을 결정하는 데 사용된다. env는 검색할 Environment Record를 명시적으로 제공하는 데 사용할 수 있다. It performs the following steps when called:

  1. env가 제공되지 않았거나 envundefined이면
    1. envrunning execution context의 LexicalEnvironment로 설정한다.
  2. 단언: envEnvironment Record이다.
  3. strict를 (평가 중인) 구문 생성 규칙에 대한 IsStrict의 결과로 둔다.
  4. GetIdentifierReference(env, name, strict)를 반환한다.
Note

ResolveBinding의 결과는 항상 [[ReferencedName]] 필드가 nameReference Record이다.

9.4.3 GetThisEnvironment ( )

The abstract operation GetThisEnvironment takes no arguments and returns Environment Record. 현재 this 키워드의 바인딩을 제공하는 Environment Record를 찾는다. It performs the following steps when called:

  1. envrunning execution context의 LexicalEnvironment로 둔다.
  2. 반복,
    1. existsenv.HasThisBinding()으로 둔다.
    2. existstrue이면 env를 반환한다.
    3. outerenv.[[OuterEnv]]로 둔다.
    4. 단언: outernull이 아니다.
    5. envouter로 설정한다.
Note

2 단계의 루프는 환경들의 리스트가 항상 this 바인딩을 가진 전역 환경으로 끝나므로 반드시 종료된다.

9.4.4 ResolveThisBinding ( )

The abstract operation ResolveThisBinding takes no arguments and returns ECMAScript 언어 값을 담는 normal completion 또는 throw completion. running execution context의 LexicalEnvironment를 사용하여 this 키워드의 바인딩을 결정한다. It performs the following steps when called:

  1. envRecGetThisEnvironment()로 둔다.
  2. envRec.GetThisBinding()을 반환한다.

9.4.5 GetNewTarget ( )

The abstract operation GetNewTarget takes no arguments and returns Object 또는 undefined. running execution context의 LexicalEnvironment를 사용하여 NewTarget 값을 결정한다. It performs the following steps when called:

  1. envRecGetThisEnvironment()로 둔다.
  2. 단언: envRec[[NewTarget]] 필드를 가진다.
  3. envRec.[[NewTarget]]을 반환한다.

9.4.6 GetGlobalObject ( )

The abstract operation GetGlobalObject takes no arguments and returns Object. 현재 running execution context가 사용하는 전역 객체를 반환한다. It performs the following steps when called:

  1. currentRealmcurrent Realm Record로 둔다.
  2. currentRealm.[[GlobalObject]]를 반환한다.

9.5 잡과 잡을 대기열에 넣기 위한 호스트 연산(Jobs and Host Operations to Enqueue Jobs)

Job은 파라미터가 없는 추상 클로저(Abstract Closure)로, 다른 ECMAScript 계산이 현재 진행 중이지 않을 때 ECMAScript 계산을 개시한다.

잡은 특정 에이전트 내에서 ECMAScript 호스트 환경에 의해 실행이 스케줄된다. 이 명세는 잡을 스케줄하기 위해 HostEnqueueGenericJob, HostEnqueueFinalizationRegistryCleanupJob, HostEnqueuePromiseJob, HostEnqueueTimeoutJob 호스트 훅을 기술한다. 이 명세의 호스트 훅들은 잡 스케줄링에 추가로 부과되는 제약들에 따라 조직되어 있다. 호스트는 잡을 스케줄하는 추가적인 추상 연산을 정의할 수 있다. 그러한 연산은 Job 추상 클로저와 realm(Realm Record 또는 null)을 인자로 받는다. Realm Record가 제공되면, 그 연산들은 해당 realm을 소유한 에이전트에서 미래의 어느 시점에 그 realm 안에서 잡이 수행되도록 스케줄한다. realm이 대신 null로 제공되면, 그 잡은 ECMAScript 코드를 평가하지 않는다. 구현은 다음 요구 사항을 따라야 한다:

  • 미래의 어떤 시점에, 그 잡이 스케줄된 에이전트에 실행 중인 컨텍스트가 없고 그 에이전트의 실행 컨텍스트 스택이 비어 있을 때, 구현은 반드시:
    1. 호스트 정의 준비 단계를 수행한다.
    2. Invoke Job 추상 클로저를 호출한다.
    3. 호스트 정의 정리 단계를 수행하며, 그 후 실행 컨텍스트 스택은 비어 있어야 한다.
  • 어느 시점에도 하나의 에이전트에서 동시에 평가 중인 Job은 하나만 존재할 수 있다.
  • Job의 평가가 시작되면, 그 에이전트에서 다른 어떤 Job의 평가가 시작되기 전에 완료까지 실행되어야 한다(run to completion).
  • 추상 클로저는 오류 처리를 자체적으로 구현하여 정상 완료(normal completion)를 반환해야 한다.
Note 1
호스트 환경은 스케줄링 측면에서 모든 Job을 동일하게 취급할 필요가 없다. 예를 들어, 웹 브라우저와 Node.js는 Promise 처리 잡을 다른 작업보다 더 높은 우선순위로 다룬다; 향후 기능은 그렇게 높은 우선순위로 다루어지지 않는 잡을 추가할 수 있다.

어떤 특정 시점에, 다음 모든 조건이 참이라면 scriptOrModule(Script Record, Module Record, 또는 null)은 active script or module(활성 스크립트 또는 모듈)이다:

  • GetActiveScriptOrModule() 결과가 scriptOrModule이다.
  • scriptOrModule이 Script Record 또는 Module Record라면, ec를 실행 컨텍스트 스택의 최상단에서 ScriptOrModule 구성 요소가 scriptOrModule인 실행 컨텍스트로 둔다. ecRealm 구성 요소는 scriptOrModule.[[Realm]]이다.

어떤 특정 시점에, 다음 모든 조건이 참이면 실행은 ECMAScript 코드를 평가할 준비가 되었다(prepared to evaluate ECMAScript code)고 한다:

  • 실행 컨텍스트 스택이 비어 있지 않다.
  • 실행 컨텍스트 스택 최상단 실행 컨텍스트의 Realm 구성 요소가 Realm Record이다.
Note 2

호스트 환경은 실행 컨텍스트들을 실행 컨텍스트 스택에 push하여 코드를 평가할 준비를 시킬 수 있다. 구체적인 단계는 구현 정의이다.

Realm의 구체적 선택은 호스트 환경에 달려 있다. 이 초기 실행 컨텍스트와 Realm은 어떤 콜백 함수가 호출되기 전까지만 사용된다. Promise 핸들러 같은 잡 관련 콜백 함수가 호출되면, 그 호출은 자체 실행 컨텍스트와 Realm을 push한다.

특정 종류의 Job은 추가적인 적합성 요구 사항을 가진다.

9.5.1 JobCallback 레코드(JobCallback Records)

JobCallback Record함수 객체호스트 정의 값을 저장하기 위해 사용되는 Record 값이다. 호스트가 대기열에 넣은 Job을 통해 호출되는 함수 객체는 추가적인 호스트 정의 컨텍스트를 가질 수 있다. 이 상태를 전파하기 위해, Job 추상 클로저는 함수 객체를 직접 캡처하고 호출하지 않아야 한다. 대신 HostMakeJobCallbackHostCallJobCallback을 사용한다.

Note

예를 들어 WHATWG HTML 명세(https://html.spec.whatwg.org/)는 Promise 콜백에 대해 incumbent settings object를 전파하기 위해 호스트 정의 값을 사용한다.

JobCallback Record는 Table 26에 나열된 필드를 가진다.

Table 26: JobCallback Record 필드(JobCallback Record Fields)
필드 이름(Field Name) 값(Value) 의미(Meaning)
[[Callback]] 함수 객체 Job이 호출될 때 호출할 함수.
[[HostDefined]] anything (기본값은 empty) 호스트 사용을 위한 예약 필드.

9.5.2 HostMakeJobCallback ( callback )

The host-defined abstract operation HostMakeJobCallback takes argument callback (함수 객체) and returns JobCallback Record.

HostMakeJobCallback 구현은 다음 요구 사항을 따라야 한다:

HostMakeJobCallback의 기본 구현은 호출될 때 다음 단계를 수행한다:

  1. JobCallback Record { [[Callback]]: callback, [[HostDefined]]: empty }를 반환한다.

웹 브라우저가 아닌 ECMAScript 호스트는 HostMakeJobCallback의 기본 구현을 사용해야 한다.

Note

이는 콜백이 궁극적으로 스케줄되고 실행되도록 책임지는 함수에 콜백이 전달되는 시점에 호출된다. 예를 들어, promise.then(thenAction)은 반응 Job이 스케줄되는 시점이 아니라 Promise.prototype.then을 호출하는 시점에 thenAction에 대해 MakeJobCallback을 호출한다.

9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList )

The host-defined abstract operation HostCallJobCallback takes arguments jobCallback (JobCallback Record), V (ECMAScript 언어 값), and argumentsList (ECMAScript 언어 값들의 List) and returns ECMAScript 언어 값을 담는 normal completion 또는 throw completion.

HostCallJobCallback 구현은 다음 요구 사항을 따라야 한다:

  • Call(jobCallback.[[Callback]], V, argumentsList)의 결과를 수행하고 반환해야 한다.
Note

이 요구 사항은 호스트가 이 명세에서 정의된 함수 객체[[Call]] 동작을 변경할 수 없음을 의미한다.

HostCallJobCallback의 기본 구현은 호출될 때 다음 단계를 수행한다:

  1. 단언: IsCallable(jobCallback.[[Callback]])가 true이다.
  2. Call(jobCallback.[[Callback]], V, argumentsList)를 반환한다.

웹 브라우저가 아닌 ECMAScript 호스트는 HostCallJobCallback의 기본 구현을 사용해야 한다.

9.5.4 HostEnqueueGenericJob ( job, realm )

The host-defined abstract operation HostEnqueueGenericJob takes arguments job (Job 추상 클로저) and realm (Realm Record) and returns unused. realm.[[AgentSignifier]]로 표시된 에이전트에서 realm 내에 job을 미래의 어느 시점에 수행하도록 스케줄한다. 이 알고리즘과 함께 사용되는 추상 클로저는 우선순위나 순서 같은 추가 제약 없이 스케줄되는 것을 의도한다.

HostEnqueueGenericJob 구현은 9.5의 요구 사항을 따라야 한다.

9.5.5 HostEnqueuePromiseJob ( job, realm )

The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (Job 추상 클로저) and realm (Realm Record 또는 null) and returns unused. job을 미래의 어느 시점에 수행하도록 스케줄한다. 이 알고리즘과 함께 사용되는 추상 클로저는 Promise 처리와 관련이 있거나 그렇지 않더라도 Promise 처리 연산과 동일한 우선순위로 스케줄되는 것을 의도한다.

HostEnqueuePromiseJob 구현은 9.5의 요구 사항과 아래 사항을 따라야 한다:

  • realmnull이 아니면, job이 호출될 때마다 구현은 job 호출 시점에 실행이 ECMAScript 코드를 평가할 준비가 되도록 구현 정의 단계를 수행해야 한다.
  • HostEnqueuePromiseJob이 호출되는 시점에 scriptOrModuleGetActiveScriptOrModule()으로 둔다. realmnull이 아니면, job이 호출될 때마다 구현은 scriptOrModulejob 호출 시점에 활성 스크립트 또는 모듈이 되도록 구현 정의 단계를 수행해야 한다.
  • 잡은 그들을 스케줄한 HostEnqueuePromiseJob 호출과 동일한 순서로 실행되어야 한다.
Note

NewPromiseResolveThenableJob이 반환한 잡의 realm은 보통 then 함수 객체에 대해 GetFunctionRealm을 호출한 결과이다. NewPromiseReactionJob이 반환한 잡의 realm은 핸들러가 undefined가 아니면 보통 핸들러에 대해 GetFunctionRealm을 호출한 결과이다. 핸들러가 undefined이면 realmnull이다. 두 종류의 잡 모두에서 GetFunctionRealm이 비정상적으로 완료(예: 철회된 Proxy에 대해 호출)되면 realmGetFunctionRealm 호출 시점의 현재 Realm Record이다. realmnull이면 어떤 사용자 ECMAScript 코드도 평가되지 않고 새로운 ECMAScript 객체(예: Error 객체)도 생성되지 않는다. WHATWG HTML 명세(https://html.spec.whatwg.org/)는 예를 들어 realm을 사용하여 스크립트 실행 가능 여부와 entry 개념을 확인한다.

9.5.6 HostEnqueueTimeoutJob ( timeoutJob, realm, milliseconds )

The host-defined abstract operation HostEnqueueTimeoutJob takes arguments timeoutJob (Job 추상 클로저), realm (Realm Record), and milliseconds (음이 아닌 유한 Number) and returns unused. realm.[[AgentSignifier]]로 표시된 에이전트에서 realm 내에 timeoutJob을 최소 milliseconds 밀리초 후에 수행되도록 스케줄한다.

HostEnqueueTimeoutJob 구현은 9.5의 요구 사항을 따라야 한다.

9.6 에이전트(Agents)

agent는 ECMAScript 실행 컨텍스트 집합, 실행 컨텍스트 스택, 실행 중 실행 컨텍스트(running execution context), Agent Record, 그리고 executing thread로 구성된다. executing thread를 제외한 구성 요소들은 오직 그 에이전트에만 속한다.

에이전트의 executing thread는 다른 에이전트와 독립적으로 그 에이전트의 실행 컨텍스트들에 대해 알고리즘 단계를 실행한다. 단, 여러 에이전트가 하나의 executing thread를 공유할 수 있는데, 그 공유하는 에이전트 중 어느 것도 Agent Record[[CanBlock]] 필드가 true이면 안 된다.

Note 1

예를 들어 일부 웹 브라우저는 서로 관계없는 여러 탭이 단일 executing thread를 공유한다.

에이전트의 executing thread가 알고리즘 단계를 실행하는 동안, 그 에이전트는 그 단계들의 surrounding agent(둘러싼 에이전트)이다. 그 단계들은 둘러싼 에이전트를 사용하여 에이전트가 보유한 명세 수준 실행 객체—실행 중 실행 컨텍스트, 실행 컨텍스트 스택, Agent Record의 필드—에 접근한다.

agent signifier(에이전트 식별자)는 에이전트를 식별하기 위해 사용되는 전역적으로 고유한 불투명 값이다.

Table 27: Agent Record 필드(Agent Record Fields)
필드 이름(Field Name) 값(Value) 의미(Meaning)
[[LittleEndian]] Boolean 알고리즘 GetValueFromBufferSetValueInBuffer가 필요할 때 isLittleEndian 파라미터에 대해 계산되는 기본 값. 선택은 구현 정의이며 구현에 가장 효율적인 대안을 사용해야 한다. 한 번 관측된 후에는 변경될 수 없다.
[[CanBlock]] Boolean 에이전트가 블록(block)될 수 있는지 여부를 결정.
[[Signifier]] agent signifier 에이전트를 그 에이전트 클러스터 내에서 고유하게 식별.
[[IsLockFree1]] Boolean 1-byte 값에 대한 원자적 연산이 lock-free이면 true, 아니면 false.
[[IsLockFree2]] Boolean 2-byte 값에 대한 원자적 연산이 lock-free이면 true, 아니면 false.
[[IsLockFree8]] Boolean 8-byte 값에 대한 원자적 연산이 lock-free이면 true, 아니면 false.
[[CandidateExecution]] candidate execution Record 메모리 모델 참조.
[[KeptAlive]] Objects 또는 Symbols 중 하나의 List 초기에는 새 빈 List로, 현재 Job 끝까지 유지(kept alive)되어야 하는 객체 및/또는 심볼들의 목록.
[[ModuleAsyncEvaluationCount]] 정수 초기값 0. 비동기 또는 비동기 의존성을 가진 모듈들의 [[AsyncEvaluationOrder]] 필드에 고유 증가값을 할당하는 데 사용.

[[Signifier]], [[IsLockFree1]], [[IsLockFree2]]의 값은 에이전트 클러스터의 어떤 에이전트에 의해 관측된 후에는 변경될 수 없다.

Note 2

[[IsLockFree1]][[IsLockFree2]]의 값은 반드시 하드웨어에 의해 결정되는 것은 아니며, 시간에 따라 또는 ECMAScript 구현 간에 달라질 수 있는 구현 선택을 반영할 수도 있다.

[[IsLockFree4]] 필드는 없다: 4-byte 원자 연산은 항상 lock-free이다.

실제로 어떤 종류의 락을 사용해 원자 연산이 구현된다면 그 연산은 lock-free가 아니다. Lock-free는 wait-free를 의미하지 않는다: lock-free 원자 연산을 완료하는 데 필요한 기계 단계 수에 상한은 없다.

크기 n의 원자 접근이 lock-free라고 해서 크기 n의 비원자(non-atomic) 접근의 (인지된) 원자성에 대해 아무것도 의미하지 않는다. 특히 비원자 접근은 여전히 여러 개의 별도 메모리 접근 시퀀스로 수행될 수 있다. 세부 사항은 ReadSharedMemoryWriteSharedMemory 참조.

Note 3

에이전트는 명세 메커니즘이며 ECMAScript 구현의 특정 실체에 대응할 필요가 없다.

9.6.1 AgentSignifier ( )

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

  1. AR를 둘러싼 에이전트의 Agent Record로 둔다.
  2. AR.[[Signifier]]를 반환한다.

9.6.2 AgentCanSuspend ( )

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

  1. AR를 둘러싼 에이전트의 Agent Record로 둔다.
  2. AR.[[CanBlock]]를 반환한다.
Note

일부 환경에서는 특정 에이전트가 일시중단(suspend)되는 것이 타당하지 않을 수 있다. 예를 들어 웹 브라우저 환경에서는 문서의 메인 이벤트 처리 스레드를 일시중단하지 않는 것이 합리적일 수 있지만 워커의 이벤트 처리 스레드는 가능하게 할 수 있다.

9.6.3 IncrementModuleAsyncEvaluationCount ( )

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

  1. AR를 둘러싼 에이전트의 Agent Record로 둔다.
  2. countAR.[[ModuleAsyncEvaluationCount]]로 둔다.
  3. AR.[[ModuleAsyncEvaluationCount]]count + 1로 설정한다.
  4. count를 반환한다.
Note

이 값은 보류 중(pending) 모듈 사이의 상대적 평가 순서를 추적하기 위해서만 사용된다. 보류 중인 모듈이 없다면 구현은 관측 불가능하게 [[ModuleAsyncEvaluationCount]]를 0으로 재설정할 수 있다.

9.7 에이전트 클러스터(Agent Clusters)

agent cluster는 공유 메모리를 조작함으로써 통신할 수 있는 에이전트들의 최대 집합이다.

Note 1

서로 다른 에이전트 내의 프로그램들은 명시되지 않은 수단으로 메모리를 공유할 수 있다. 최소한 SharedArrayBuffers의 백업 메모리는 클러스터의 에이전트들 간에 공유될 수 있다.

메시지 전달로 통신할 수 있지만 메모리를 공유할 수 없는 에이전트들도 있을 수 있으며, 그들은 절대 같은 에이전트 클러스터에 속하지 않는다.

모든 에이전트는 정확히 하나의 에이전트 클러스터에 속한다.

Note 2

클러스터의 에이전트들이 어떤 특정 시점에 모두 살아 있을 필요는 없다. 에이전트 A가 다른 에이전트 B를 생성하고, 그 후 A가 종료되고 B가 에이전트 C를 생성한다면, AB와 일부 메모리를 공유할 수 있었고 BC와 일부 메모리를 공유할 수 있었다면 세 에이전트는 같은 클러스터에 속한다.

클러스터 내 모든 에이전트는 각각의 Agent Record에서 [[LittleEndian]] 필드에 대해 동일한 값을 가져야 한다.

Note 3

에이전트 클러스터 내의 에이전트들이 [[LittleEndian]] 값이 서로 다르다면, 다중 바이트 데이터에 대해 공유 메모리를 사용하는 것이 어려워진다.

클러스터 내 모든 에이전트는 [[IsLockFree1]] 필드에 대해 동일한 값을 가져야 하며 [[IsLockFree2]] 필드도 마찬가지이다.

클러스터 내 모든 에이전트는 각각의 Agent Record에서 [[Signifier]] 필드에 대해 서로 다른 값을 가져야 한다.

임베딩은 에이전트의 지식이나 협력 없이 에이전트를 비활성화(진행 중단)하거나 활성화(진행 재개)할 수 있다. 임베딩이 그렇게 한다면, 클러스터 내 일부 에이전트만 활성 상태로 남기고 다른 에이전트들을 무기한 비활성화된 상태로 두어서는 안 된다.

Note 4

위 제한의 목적은 어떤 에이전트가 다른 에이전트가 비활성화되었기 때문에 데드락 또는 기아(starvation)에 빠지는 상황을 피하기 위함이다. 예를 들어, 창 윈도우의 어떤 문서에도 독립적인 수명(lifetime)을 가진 HTML 공유 워커가 그런 독립 문서의 전용(dedicated) 워커와 메모리를 공유할 수 있고, 그 후 문서와 전용 워커가 (예: 문서가 히스토리에 들어가면서) 비활성화되었으며 전용 워커가 락을 보유한 상태이고, 공유 워커가 락을 획득하려 하면 공유 워커는 전용 워커가 다시 활성화될 때까지(혹은 영원히) 블록된다. 그동안 다른 윈도우에서 공유 워커에 접근하려는 다른 워커들은 기아 상태에 빠진다.

이 제한의 함의는 임베딩 내에서 동일한 suspend/wake 집합에 속하지 않는 에이전트들 사이에서는 메모리를 공유할 수 없다는 것이다.

임베딩은 에이전트 클러스터의 다른 에이전트의 사전 지식이나 협력 없이 에이전트를 종료할 수 있다. 에이전트가 자체 또는 클러스터 내 다른 에이전트의 프로그래밍 동작이 아니라 클러스터 외부의 힘에 의해 종료된다면, 임베딩은 두 전략 중 하나를 선택해야 한다: 클러스터의 모든 에이전트를 종료하거나, 클러스터의 에이전트들이 협력하여 종료를 감지할 수 있도록 신뢰 가능한 API를 제공하되, 종료 데이터는 종료된 에이전트를 식별하기에 충분한 정보를 포함해야 한다.

Note 5

그러한 종료 유형의 예로는: 별도 프로세스에서 실행 중인 에이전트를 운영체제나 사용자가 종료하는 경우; per-agent 자원 계정이 에이전트가 runaway임을 나타낼 때 같은 프로세스에서 다른 에이전트와 함께 실행 중인 에이전트를 임베딩 자체가 종료하는 경우 등이 있다.

다음 명세 값 각각과 그들로부터 추이적으로 도달 가능한 값들은 정확히 하나의 에이전트 클러스터에 속한다.

클러스터 내 어떤 에이전트가 ECMAScript 코드를 평가하기 이전에, 클러스터의 모든 에이전트에 대한 Agent Record[[CandidateExecution]] 필드는 초기 candidate execution으로 설정된다. 초기 candidate execution은 비어 있는 candidate execution으로, 그 [[EventsRecords]] 필드는 각 에이전트에 대해 [[AgentSignifier]] 필드가 그 에이전트의 agent signifier이고 [[EventList]][[AgentSynchronizesWith]] 필드가 빈 ListAgent Events Record를 포함하는 List이다.

Note 6

에이전트 클러스터의 모든 에이전트는 Agent Record[[CandidateExecution]] 필드에서 동일한 candidate execution을 공유한다. candidate execution은 메모리 모델에서 사용되는 명세 메커니즘이다.

Note 7

에이전트 클러스터는 명세 메커니즘이며 ECMAScript 구현의 특정 실체에 대응할 필요가 없다.

9.8 Forward Progress

에이전트가 forward progress를 만든다(make forward progress)는 것은 이 명세에 따라 평가 단계(evaluation step)를 수행하는 것이다.

에이전트의 실행 중 실행 컨텍스트가 외부 이벤트를 동기적으로 무기한 기다릴 때, 그 에이전트는 blocked가 된다. Agent Record[[CanBlock]] 필드가 true인 에이전트만 이런 의미에서 blocked 상태가 될 수 있다. unblocked 에이전트는 blocked가 아닌 에이전트이다.

구현은 다음을 보장해야 한다:

  • 전용 executing thread를 가진 모든 unblocked 에이전트는 결국 forward progress를 만든다.
  • executing thread를 공유하는 에이전트 집합에서는 하나의 에이전트가 결국 forward progress를 만든다.
  • 에이전트는 차단(blocking)을 제공하는 명시적 API를 통한 경우를 제외하고 다른 에이전트를 blocked 상태로 만들지 않는다.
Note

이는 메모리 모델의 liveness 보장과 함께 모든 seq-cst 쓰기가 결국 모든 에이전트에 관측 가능해짐을 보장한다.

9.9 WeakRef 및 FinalizationRegistry 대상 처리 모델(Processing Model of WeakRef and FinalizationRegistry Targets)

9.9.1 목표(Objectives)

이 명세는 어떤 객체나 심볼이 가비지 컬렉션될 것이라는 보장을 제공하지 않는다. live가 아닌 객체나 심볼은 긴 시간이 지난 후 해제되거나 전혀 해제되지 않을 수 있다. 이런 이유로 본 명세는 가비지 컬렉션에 의해 트리거되는 동작을 설명할 때 "may"라는 용어를 사용한다.

WeakRefFinalizationRegistry의 의미론은 특정 시점에 발생하는 두 연산에 기반한다:

  • WeakRef.prototype.deref가 호출될 때, ( undefined 가 반환되지 않는 경우) 참조 대상(referent)은 이후의 동기적 접근에서 동일한 값을 반환할 수 있도록 살아 있게 유지된다. 이 목록(list)은 ClearKeptObjects 추상 연산을 사용해 동기 작업이 완료될 때 리셋된다.
  • FinalizationRegistry에 등록된 객체나 심볼이 도달 불가능(unreachable)이 되면, FinalizationRegistry의 cleanup 콜백 호출이 동기 ECMAScript 실행이 완료된 후 언젠가 수행될 수 있다. FinalizationRegistry 정리는 CleanupFinalizationRegistry 추상 연산으로 수행된다.

이 두 동작(ClearKeptObjects 또는 CleanupFinalizationRegistry)은 동기 ECMAScript 실행을 중단(interrupt)해서는 안 된다. 호스트는 더 긴 동기 ECMAScript 실행 구간을 구성할 수 있으므로, 이 명세는 ClearKeptObjectsCleanupFinalizationRegistry의 스케줄링을 호스트 환경에 위임한다.

일부 ECMAScript 구현에는 ECMAScript가 유휴(idle) 상태일 때를 포함해 백그라운드로 실행되는 가비지 컬렉터 구현이 포함되어 있다. 호스트 환경CleanupFinalizationRegistry를 스케줄하도록 하면, 구현이 파이널라이저 작업을 실행하기 위해 ECMAScript 실행을 재개하여 유지 중인 값을 해제함으로써 전체 메모리 사용량을 줄일 수 있다.

9.9.2 Liveness

객체 및/또는 심볼의 집합 S에 대해 hypothetical WeakRef-oblivious(가설적 WeakRef-무관) 실행이란, S의 요소인 참조 대상을 가진 WeakRefWeakRefDeref 추상 연산이 항상 undefined를 반환하는 실행을 말한다.

Note 1
WeakRef-obliviousness와 liveness는 두 개념을 함께 포착한다. 첫째, WeakRef 자체는 그 참조 대상을 살아 있게 유지하지 않는다. 둘째, liveness에서의 사이클이 값이 live임을 의미하지는 않는다. 구체적으로, v의 liveness 결정이 WeakRef referent r의 liveness 결정에 의존한다면, r의 liveness는 v의 liveness를 가정할 수 없는데, 이는 순환 논리이기 때문이다.
Note 2
WeakRef-obliviousness는 사이클을 고려하기 위해 개별 값이 아닌 객체 또는 심볼 집합에 대해 정의된다. 개별 값에 대해 정의된다면, 사이클 내 WeakRef referent는 사이클 내 다른 WeakRef referent를 통해서만 그 정체성이 관측되더라도 live로 간주될 것이다.
Note 3
구어적으로는, 어떤 개별 객체나 심볼이 속한 모든 집합이 live이면 그 객체나 심볼을 live라고 말한다.

평가 도중 어느 시점에서든, 객체 및/또는 심볼 집합 S가 아래 조건 중 하나를 만족하면 live로 간주한다:

  • S의 어떤 요소라도 어떤 에이전트의 [[KeptAlive]] List에 포함된다.
  • S에 대한 어떤 유효한 미래의 가설적 WeakRef-oblivious 실행이 S 내 값의 정체성을 관측한다.
Note 4
두 번째 조건은 값의 정체성이 WeakRef 이외의 수단으로 관측 가능하다면 그 값이 live라는 직관을 포착하려는 것이다. 값의 정체성은 엄격 동등성 비교를 관측하거나 Map의 키로 사용되는 값을 관측함으로써 관측될 수 있다.
Note 5

필드, 내부 슬롯, 프로퍼티 내 객체 또는 심볼의 존재는 그 값이 live임을 의미하지 않는다. 예를 들어 해당 값이 프로그램에 다시 전달되지 않는다면 관측될 수 없다.

이는 WeakMap의 키, WeakSet의 멤버, 그리고 FinalizationRegistry Cell record의 [[WeakRefTarget]][[UnregisterToken]] 필드에 해당한다.

위 정의는 WeakMap에서 어떤 키가 live가 아니면 그에 대응하는 값도 반드시 live일 필요는 없음을 의미한다.

Note 6
Liveness는 엔진이 비워서는 안 되는 WeakRef에 대해 보장해야 하는 하한(lower bound)이다. 여기 정의된 Liveness는 결정 불가능(undecidable)하다. 실제로 엔진은 도달 가능성 같은 보수적 근사(approximation)를 사용한다. 구현 재량의 폭이 크다.

9.9.3 Execution

어느 시점에서든 객체 및/또는 심볼 집합 Slive가 아니라면, ECMAScript 구현은 다음 단계를 원자적으로 수행할 수 있다:

  1. S의 각 요소 value에 대해
    1. ref.[[WeakRefTarget]]value인 각 WeakRef ref에 대해
      1. ref.[[WeakRefTarget]]empty로 설정한다.
    2. fg.[[Cells]][[WeakRefTarget]]valueRecord cell을 포함하는 각 FinalizationRegistry fg에 대해
      1. cell.[[WeakRefTarget]]empty로 설정한다.
      2. 선택적으로 HostEnqueueFinalizationRegistryCleanupJob(fg)를 수행한다.
    3. map.[[WeakMapData]][[Key]]valueRecord r을 포함하는 각 WeakMap map에 대해
      1. r.[[Key]]empty로 설정한다.
      2. r.[[Value]]empty로 설정한다.
    4. set.[[WeakSetData]]value를 포함하는 각 WeakSet set에 대해
      1. 값이 valueset.[[WeakSetData]]의 요소를 값이 empty인 요소로 교체한다.
Note 1

Liveness 정의와 함께, 본 절은 구현이 WeakRef에 관해 적용할 수 있는 최적화들을 규정한다.

객체의 정체성을 관측하지 않고 객체에 접근하는 것이 가능하다. 정체성이 관측되지 않는, escape하지 않는 객체의 프로퍼티에 대해 dead variable elimination, scalar replacement 같은 최적화는 허용된다. 그러한 최적화는 해당 객체를 가리키는 WeakRef들을 관측 가능하게 비울 수 있다.

반면 객체의 정체성이 관측 가능하고 그 객체가 WeakRef[[WeakRefTarget]] 내부 슬롯에 있다면, WeakRef를 관측 가능하게 비워 버리는 rematerialization 같은 최적화는 금지된다.

HostEnqueueFinalizationRegistryCleanupJob 호출이 선택적이므로, FinalizationRegistry에 등록된 객체는 반드시 그 FinalizationRegistrylive로 유지하지 않는다. 구현은 FinalizationRegistry 자체가 dead가 되었거나 애플리케이션이 종료 중인 경우 등 어떤 이유로든 FinalizationRegistry 콜백을 생략할 수 있다.

Note 2

구현은 live가 아닌 객체나 심볼의 최대 집합에 대해 WeakRef를 반드시 비울 필요는 없다.

구현이 WeakRef를 비울 live가 아닌 집합 S를 선택한다면, 이 정의는 S 내 모든 값에 대한 WeakRef를 동시에 비우도록 요구한다. 즉, 값 v를 가리키는 WeakRef 하나를 비우면서, 비워지지 않았다면 v의 값을 관측할 수도 있는 다른 WeakRef를 비우지 않은 채 두는 것은 적합(conformant)하지 않다.

9.9.4 호스트 훅(Host Hooks)

9.9.4.1 HostEnqueueFinalizationRegistryCleanupJob ( finalizationRegistry )

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

finalizationRegistry를 캡처하고 호출 시 다음 단계를 수행하는, 파라미터 없는 새 Job 추상 클로저 cleanupJob을 둔다:

  1. cleanupResultCompletion(CleanupFinalizationRegistry(finalizationRegistry))로 둔다.
  2. cleanupResultabrupt completion이면 오류 보고를 위한 호스트 정의 단계를 수행한다.
  3. unused를 반환한다.

HostEnqueueFinalizationRegistryCleanupJob 구현은 가능하다면 미래의 어느 시점에 cleanupJob이 수행되도록 스케줄한다. 또한 9.5의 요구 사항을 따라야 한다.

9.10 ClearKeptObjects ( )

The abstract operation ClearKeptObjects takes no arguments and returns unused. ECMAScript 구현은 동기적인 ECMAScript 실행 시퀀스가 완료될 때 ClearKeptObjects를 호출하는 것이 기대된다. It performs the following steps when called:

  1. agentRecord를 둘러싼 에이전트의 Agent Record로 둔다.
  2. agentRecord.[[KeptAlive]]를 새 빈 List로 설정한다.
  3. 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. agentRecord를 둘러싼 에이전트의 Agent Record로 둔다.
  2. agentRecord.[[KeptAlive]]value를 추가(Append)한다.
  3. unused를 반환한다.
Note
추상 연산 AddToKeptObjects가 어떤 대상 객체나 심볼과 함께 호출되면, ClearKeptObjects가 호출될 때까지 그 대상을 강하게 참조하는 목록에 대상을 추가한다.

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. 단언: finalizationRegistry[[Cells]][[CleanupCallback]] 내부 슬롯을 가진다.
  2. callbackfinalizationRegistry.[[CleanupCallback]]로 둔다.
  3. finalizationRegistry.[[Cells]][[WeakRefTarget]]emptyRecord cell을 포함하는 동안, 구현은 다음 단계를 수행할 수 있다:
    1. 그러한 cell 중 임의의 하나를 선택한다.
    2. finalizationRegistry.[[Cells]]에서 cell을 제거한다.
    3. HostCallJobCallback(callback, undefined, « cell.[[HeldValue]] »)를 수행한다.
  4. unused를 반환한다.

9.13 CanBeHeldWeakly ( v )

The abstract operation CanBeHeldWeakly takes argument v (an ECMAScript language value) and returns a Boolean. v가 약한 참조(weak reference)에 사용하기에 적합한 경우에만 true를 반환한다. 약한 참조에 사용하기에 적합한 값만이 WeakMap의 키, WeakSet의 요소, WeakRef의 target, 또는 FinalizationRegistry의 target들 중 하나가 될 수 있다. It performs the following steps when called:

  1. v가 Object이면 true를 반환한다.
  2. v가 Symbol이고 KeyForSymbol(v)이 undefined이면 true를 반환한다.
  3. false를 반환한다.
Note

언어 정체성(language identity)이 없는 언어 값은 사전 참조 없이도 나타날 수 있으며 약한 참조로 사용하기에 부적합하다. Symbol.for로 생성된 Symbol 값은 다른 Symbol 값과 달리 언어 정체성이 없으므로 약한 참조로 사용하기에 부적합하다. Well-known symbols는 수집되지 않을 가능성이 높지만, 그 수가 제한되어 있고 다양한 구현 방식으로 관리 가능하므로 약한 참조로 사용하기에 적합한 것으로 간주된다. 그러나 live한 WeakMap 안의 well-known symbol에 연관된 어떤 값도 수집되지 않아 메모리 자원이 “누수”될 가능성이 있다.