9 실행 가능한 코드와 실행 컨텍스트(Executable Code and Execution Contexts)
9.1 Environment Record
Environment Record는 ECMAScript 코드의 렉시컬 중첩 구조를 기반으로 Identifier들을 특정 변수와 함수에 연계(association)하기 위해 사용되는 명세 타입이다. 보통 Environment Record는 FunctionDeclaration, BlockStatement, TryStatement의 Catch 절과 같은 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)
Global Environment Record는 Script 전역 선언에 사용된다. 바깥 환경을 가지지 않으며 [[OuterEnv]]는 null이다. 사전 채워진 식별자 바인딩을 가질 수 있고 관련된 전역 객체를 포함하며 그 전역 객체의 프로퍼티는 일부 전역 환경 식별자 바인딩을 제공한다. ECMAScript 코드가 실행되면서 전역 객체에 프로퍼티가 추가될 수 있고 초기 프로퍼티가 수정될 수 있다.
Environment Record가 문자열 값 N에 대한 바인딩을 가지는지 결정한다. 있다면 true, 없으면 false를 반환.
CreateMutableBinding(N, D)
Environment Record에 새이지만 아직 초기화되지 않은 변경 가능(mutable) 바인딩을 생성한다. 문자열 값 N은 바운드 이름 텍스트다. Boolean 인자 D가 true이면 해당 바인딩은 이후 삭제될 수 있다.
CreateImmutableBinding(N, S)
Environment Record에 새이지만 아직 초기화되지 않은 변경 불가능(immutable) 바인딩을 생성한다. 문자열 값 N은 바운드 이름 텍스트다. S가 true이면 초기화 후 설정하려는 모든 시도는 (참조하는 연산의 strict 모드 설정과 무관하게) 항상 예외를 던진다.
이미 존재하는 mutable 바인딩의 값을 설정한다. 문자열 값 N은 바운드 이름 텍스트, V는 값, S는 Boolean 플래그. S가 true이고 바인딩을 설정할 수 없다면 TypeError 예외를 던진다.
GetBindingValue(N, S)
이미 존재하는 바인딩의 값을 반환한다. 문자열 값 N은 바운드 이름 텍스트. S는 strict 모드 코드에서 기원했거나 strict 모드 참조语 의미를 요구하는지 식별하는 데 사용된다. S가 true이고 바인딩이 존재하지 않으면 ReferenceError를 던진다. 바인딩이 존재하지만 초기화되지 않았다면 S 값과 무관하게 ReferenceError를 던진다.
DeleteBinding(N)
바인딩을 삭제한다. 문자열 값 N은 바운드 이름 텍스트. N에 대한 바인딩이 존재하면 제거하고 true 반환. 존재하지만 제거 불가하면 false 반환. 존재하지 않으면 true 반환.
각 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 RecordenvRec takes argument N (String) and returns Boolean을 담는 normal completion. 인수 식별자가 이 레코드에 의해 바인딩된 식별자 중 하나인지 판정한다. It performs the following steps when called:
envRec이 N에 대한 바인딩을 가지고 있으면 true 반환.
false 반환.
9.1.1.1.2 CreateMutableBinding ( N, D )
The CreateMutableBinding concrete method of Declarative Environment RecordenvRec takes arguments N (String) and D (Boolean) and returns unused를 담는 normal completion. 초기화되지 않은 이름 N에 대한 새로운 mutable 바인딩을 생성한다. 이미 존재해서는 안 된다. D가 true이면 삭제 대상 표시. It performs the following steps when called:
단언: envRec은 이미 N 바인딩을 갖지 않는다.
envRec 안에 N에 대한 초기화되지 않은 mutable 바인딩을 생성하고 D가 true이면 이후 DeleteBinding 호출로 삭제 가능함을 기록.
unused 반환.
9.1.1.1.3 CreateImmutableBinding ( N, S )
The CreateImmutableBinding concrete method of Declarative Environment RecordenvRec takes arguments N (String) and S (Boolean) and returns unused를 담는 normal completion. 초기화되지 않은 이름 N에 대한 immutable 바인딩을 생성. 이미 존재해서는 안 된다. S가 true이면 strict 바인딩으로 표시. It performs the following steps when called:
단언: envRec은 이미 N 바인딩을 갖지 않는다.
envRec에 N immutable 바인딩을 생성하고 초기화되지 않았음을 기록. S가 true이면 strict 바인딩임을 기록.
unused 반환.
9.1.1.1.4 InitializeBinding ( N, V )
The InitializeBinding concrete method of Declarative Environment RecordenvRec takes arguments N (String) and V (ECMAScript 언어 값) and returns unused를 담는 normal completion. 이미 존재하는 식별자 N의 현재 바인딩 값(bound value)을 V로 설정한다. N에 대한 초기화되지 않은 바인딩이 이미 있어야 한다. It performs the following steps when called:
단언: envRec은 N에 대한 초기화되지 않은 바인딩을 가져야 한다.
envRec에서 N의 바운드 값을 V로 설정.
RecordenvRec의 N 바인딩이 초기화되었음을 기록.
unused 반환.
9.1.1.1.5 SetMutableBinding ( N, V, S )
The SetMutableBinding concrete method of Declarative Environment RecordenvRec takes arguments N (String), V (ECMAScript 언어 값), and S (Boolean) and returns unused 또는 throw completion. 식별자 N의 현재 바인딩 값을 V로 변경 시도. 보통 바인딩은 이미 존재하지만 드물게 없을 수도 있다. 바인딩이 immutable이고 S가 true이면 TypeError. It performs the following steps when called:
functionf() { eval("var x; x = (delete x, 0);"); }
9.1.1.1.6 GetBindingValue ( N, S )
The GetBindingValue concrete method of Declarative Environment RecordenvRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. 이름이 N인 바인딩된 식별자의 값을 반환. 바인딩이 존재하지만 초기화되지 않았으면 S와 무관하게 ReferenceError. It performs the following steps when called:
단언: envRec은 N 바인딩을 가진다.
envRec의 N 바인딩이 초기화되지 않았다면 ReferenceError 예외.
현재 envRec에 N으로 바인딩된 값을 반환.
9.1.1.1.7 DeleteBinding ( N )
The DeleteBinding concrete method of Declarative Environment RecordenvRec takes argument N (String) and returns Boolean을 담는 normal completion. 삭제 대상으로 명시적으로 지정된 바인딩만 삭제할 수 있다. It performs the following steps when called:
단언: envRec은 N 바인딩을 가진다.
envRec의 N 바인딩이 삭제 불가라면 false 반환.
envRec에서 N 바인딩 제거.
true 반환.
9.1.1.1.8 HasThisBinding ( )
The HasThisBinding concrete method of Declarative Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The HasSuperBinding concrete method of Declarative Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of Declarative Environment RecordenvRec takes no arguments and returns undefined. It performs the following steps when called:
undefined 반환.
9.1.1.2 Object Environment Record
각 Object Environment Record는 binding 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에 나열된 추가 상태 필드를 가진다.
The HasBinding concrete method of Object Environment RecordenvRec takes argument N (String) and returns Boolean 또는 throw completion. 연관된 binding object가 이름 N인 프로퍼티를 가지는지 판정한다. It performs the following steps when called:
bindingObject를 envRec.[[BindingObject]]로 둔다.
foundBinding을 ? HasProperty(bindingObject, N)로 둔다.
The CreateMutableBinding concrete method of Object Environment RecordenvRec takes arguments N (String) and D (Boolean) and returns unused 또는 throw completion. Environment Record의 binding object에 이름 N 프로퍼티를 생성하고 값을 undefined로 초기화. D가 true이면 새 프로퍼티 [[Configurable]]을 true, 아니면 false. It performs the following steps when called:
bindingObject를 envRec.[[BindingObject]]로 둔다.
? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }) 수행.
The InitializeBinding concrete method of Object Environment RecordenvRec takes arguments N (String) and V (ECMAScript 언어 값) and returns unused 또는 throw completion. 이름 N인 바인딩 객체 프로퍼티의 값을 V로 설정. It performs the following steps when called:
? envRec.SetMutableBinding(N, V, false) 수행.
unused 반환.
Note
이 명세에서 Object Environment Record에 대한 모든 CreateMutableBinding 사용은 같은 이름에 대한 InitializeBinding 호출로 즉시 이어지므로, 초기화 상태를 명시적으로 추적하지 않는다.
9.1.1.2.5 SetMutableBinding ( N, V, S )
The SetMutableBinding concrete method of Object Environment RecordenvRec 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:
The GetBindingValue concrete method of Object Environment RecordenvRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. binding object의 이름 N 프로퍼티 값을 반환. 존재하지 않을 경우 S에 따라 결과 결정. It performs the following steps when called:
The DeleteBinding concrete method of Object Environment RecordenvRec takes argument N (String) and returns Boolean 또는 throw completion. [[Configurable]]이 true인 환경 객체 프로퍼티에 대응되는 바인딩만 삭제 가능. It performs the following steps when called:
bindingObject를 envRec.[[BindingObject]]로 둔다.
? bindingObject.[[Delete]](N) 반환.
9.1.1.2.8 HasThisBinding ( )
The HasThisBinding concrete method of Object Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The HasSuperBinding concrete method of Object Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of Object Environment RecordenvRec takes no arguments and returns Object 또는 undefined. It performs the following steps when called:
Function Environment Record는 함수의 최상위 스코프를 나타내는 Declarative Environment Record이며 함수가 ArrowFunction이 아니면 this 바인딩을 제공한다. 함수가 ArrowFunction이 아니고 super를 참조하는 경우 그 Function Environment Record는 함수 내에서 super 메서드 호출을 수행하는 데 사용되는 상태도 포함한다.
Function Environment Record는 Table 16에 나열된 추가 상태 필드를 가진다.
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:
The HasThisBinding concrete method of Function Environment RecordenvRec takes no arguments and returns Boolean. It performs the following steps when called:
envRec.[[ThisBindingStatus]]가 lexical이면 false, 아니면 true 반환.
9.1.1.3.3 HasSuperBinding ( )
The HasSuperBinding concrete method of Function Environment RecordenvRec takes no arguments and returns Boolean. It performs the following steps when called:
envRec.[[ThisBindingStatus]]가 lexical이면 false 반환.
envRec.[[FunctionObject]].[[HomeObject]]가 undefined이면 false, 아니면 true 반환.
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:
home을 envRec.[[FunctionObject]].[[HomeObject]]로 둔다.
home이 undefined이면 undefined 반환.
단언: home은 ordinary object.
! 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)의 바인딩을 제공한다.
The HasBinding concrete method of Global Environment RecordenvRec takes argument N (String) and returns Boolean 또는 throw completion. 인수 식별자가 레코드에 의해 바인딩된 식별자 중 하나인지 판정. It performs the following steps when called:
DclRec을 envRec.[[DeclarativeRecord]]로 둔다.
! DclRec.HasBinding(N)이 true이면 true 반환.
ObjRec을 envRec.[[ObjectRecord]]로 둔다.
? ObjRec.HasBinding(N) 반환.
9.1.1.4.2 CreateMutableBinding ( N, D )
The CreateMutableBinding concrete method of Global Environment RecordenvRec takes arguments N (String) and D (Boolean) and returns unused 또는 throw completion. 초기화되지 않은 N mutable 바인딩을 새로 생성. 관련 DeclarativeRecord에 생성. 이미 존재하면 안 됨. D가 true면 삭제 가능 표시. It performs the following steps when called:
DclRec을 envRec.[[DeclarativeRecord]]로 둔다.
! DclRec.HasBinding(N)이 true이면 TypeError 예외.
! DclRec.CreateMutableBinding(N, D) 반환.
9.1.1.4.3 CreateImmutableBinding ( N, S )
The CreateImmutableBinding concrete method of Global Environment RecordenvRec takes arguments N (String) and S (Boolean) and returns unused 또는 throw completion. 초기화되지 않은 N immutable 바인딩 생성. 이미 존재하면 안 됨. S가 true이면 strict 바인딩. It performs the following steps when called:
DclRec을 envRec.[[DeclarativeRecord]]로 둔다.
! DclRec.HasBinding(N)이 true이면 TypeError 예외.
! DclRec.CreateImmutableBinding(N, S) 반환.
9.1.1.4.4 InitializeBinding ( N, V )
The InitializeBinding concrete method of Global Environment RecordenvRec takes arguments N (String) and V (ECMAScript 언어 값) and returns unused 또는 throw completion. 식별자 N의 현재 바인딩 값을 V로 설정. N에 대한 초기화되지 않은 바인딩이 이미 존재해야 한다. It performs the following steps when called:
The SetMutableBinding concrete method of Global Environment RecordenvRec takes arguments N (String), V (ECMAScript 언어 값), and S (Boolean) and returns unused 또는 throw completion. 식별자 N의 현재 바인딩 값을 V로 변경 시도. immutable 바인딩이고 S가 true이면 TypeError. 프로퍼티 N은 보통 존재하지만 없거나 현재 writable이 아닐 수도 있으며 이는 S에 따라 처리. It performs the following steps when called:
DclRec을 envRec.[[DeclarativeRecord]]로 둔다.
! DclRec.HasBinding(N)이 true이면
? DclRec.SetMutableBinding(N, V, S) 반환.
ObjRec을 envRec.[[ObjectRecord]]로 둔다.
? ObjRec.SetMutableBinding(N, V, S) 반환.
9.1.1.4.6 GetBindingValue ( N, S )
The GetBindingValue concrete method of Global Environment RecordenvRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. 식별자 N의 값을 반환. 바인딩이 초기화되지 않았으면 ReferenceError. 프로퍼티 N은 보통 존재하지만 없거나 writable이 아닐 수도 있는데 이는 S에 따라 처리. It performs the following steps when called:
DclRec을 envRec.[[DeclarativeRecord]]로 둔다.
! DclRec.HasBinding(N)이 true이면
? DclRec.GetBindingValue(N, S) 반환.
ObjRec을 envRec.[[ObjectRecord]]로 둔다.
? ObjRec.GetBindingValue(N, S) 반환.
9.1.1.4.7 DeleteBinding ( N )
The DeleteBinding concrete method of Global Environment RecordenvRec takes argument N (String) and returns Boolean 또는 throw completion. 삭제 대상으로 명시된 바인딩만 삭제 가능. It performs the following steps when called:
The HasThisBinding concrete method of Global Environment RecordenvRec takes no arguments and returns true. It performs the following steps when called:
The HasSuperBinding concrete method of Global Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of Global Environment RecordenvRec takes no arguments and returns undefined. It performs the following steps when called:
undefined 반환.
9.1.1.4.11 GetThisBinding ( )
The GetThisBinding concrete method of Global Environment RecordenvRec takes no arguments and returns Object를 담는 normal completion. It performs the following steps when called:
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:
DclRec을 envRec.[[DeclarativeRecord]]로 둔다.
! 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:
ObjRec을 envRec.[[ObjectRecord]]로 둔다.
globalObject를 ObjRec.[[BindingObject]]로 둔다.
existingProp을 ? globalObject.[[GetOwnProperty]](N)로 둔다.
existingProp이 undefined이면 false 반환.
existingProp.[[Configurable]]이 true이면 false 반환.
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:
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:
전역 함수 선언은 항상 전역 객체의 own 프로퍼티로 표현된다. 가능하면 기존 own 프로퍼티가 표준 속성 집합으로 재구성된다. 단계 7은 InitializeBinding 구체 메서드 호출과 동등하며 globalObject가 Proxy이면 동일한 Proxy 트랩 호출 순서를 만든다.
The GetBindingValue concrete method of Module Environment RecordenvRec takes arguments N (String) and S (Boolean) and returns ECMAScript 언어 값 또는 throw completion. 이름 N인 바인딩된 식별자 값을 반환. 간접 바인딩이면 대상 바인딩 값을 반환. 바인딩이 존재하지만 초기화되지 않았으면 ReferenceError. It performs the following steps when called:
The HasThisBinding concrete method of Module Environment RecordenvRec takes no arguments and returns true. It performs the following steps when called:
The GetThisBinding concrete method of Module Environment RecordenvRec takes no arguments and returns undefined를 담는 normal completion. It performs the following steps when called:
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 간접 바인딩을 생성. envRec에 N 바인딩이 이미 존재해서는 안 됨. N2는 M의 Module Environment Record에 존재하는 바인딩 이름. 새 바인딩의 값 접근은 대상 바인딩 값을 간접적으로 접근. It performs the following steps when called:
단언: envRec은 이미 N 바인딩을 갖지 않는다.
단언: M.[[Environment]]가 인스턴스화될 때 N2에 대한 direct 바인딩을 가진다.
envRec에 N immutable 간접 바인딩을 생성하여 M, N2를 대상 바인딩으로 참조하고 초기화되었음을 기록.
unused 반환.
9.1.2 Environment Record 연산(Environment Record Operations)
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:
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:
The abstract operation NewFunctionEnvironment takes arguments F (ECMAScript 함수 객체) and newTarget (Object 또는 undefined) and returns Function Environment Record. It performs the following steps when called:
The abstract operation NewGlobalEnvironment takes arguments G (Object) and thisValue (Object) and returns Global Environment Record. It performs the following steps when called:
The abstract operation ResolvePrivateIdentifier takes arguments privateEnv (PrivateEnvironment Record) and identifier (String) and returns Private Name. It performs the following steps when called:
평가되기 전에 모든 ECMAScript 코드는 하나의 realm과 연계되어야 한다. 개념적으로 realm은 일련의 intrinsic 객체, ECMAScript 전역 환경, 그 전역 환경의 범위 내에서 로드된 모든 ECMAScript 코드, 그리고 기타 관련 상태 및 자원으로 구성된다.
realm은 이 명세에서 Table 22에 지정된 필드를 가진 Realm Record로 표현된다:
템플릿 객체들은 각 realm별로 그 Realm Record의 [[TemplateMap]]을 사용하여 정규화(canonicalize)된다. 각 [[Site]] 값은 TemplateLiteral 인 Parse Node이다. 연계된 [[Array]] 값은 태그 함수에 전달되는 해당 템플릿 객체이다.
Note 1
어떤 Parse Node가 도달 불가능(unreachable)이 되면, 대응하는 [[Array]] 또한 도달 불가능해지며, 구현이 그 쌍을 [[TemplateMap]] 리스트에서 제거하더라도 관측 불가능하다.
The abstract operation InitializeHostDefinedRealm takes no arguments and returns unused를 담는 normal completion 또는 throw completion. It performs the following steps when called:
realmRec.[[Intrinsics]]의 필드들을 Table 6에 나열된 값으로 설정한다. 필드 이름은 테이블 첫 번째 열의 이름들이다. 각 필드 값은 19부터 28까지의 각 객체 명세에 따라 그 프로퍼티 값으로 완전하고 재귀적으로 채워진 새 객체 값이다. 모든 객체 프로퍼티 값은 새로 생성된 객체 값이다. 내장 함수 객체인 모든 값은 CreateBuiltinFunction(steps, length, name, slots, realmRec, prototype)을 수행하여 생성되는데, 여기서 steps는 이 명세가 제공하는 그 함수의 정의, name은 함수의 초기 "name" 프로퍼티 값, length는 함수의 초기 "length" 프로퍼티 값, slots는 (있다면) 함수의 지정된 내부 슬롯 이름들의 리스트, prototype은 함수 [[Prototype]] 내부 슬롯의 지정된 값이다. intrinsic과 그 프로퍼티 생성은 아직 생성되지 않은 객체에 대한 의존성이 없도록 순서가 정해져야 한다.
The abstract operation SetDefaultGlobalBindings takes argument realmRec (Realm Record) and returns unused를 담는 normal completion 또는 throw completion. It performs the following steps when called:
execution context는 ECMAScript 구현이 코드의 런타임 평가를 추적하기 위해 사용하는 명세 장치이다. 어느 시점에도 코드 실행 중인 에이전트당 실제로 코드를 실행하는 실행 컨텍스트는 최대 하나이다. 이는 그 에이전트의 running execution context로 알려져 있다. 이 명세에서 running execution context에 대한 모든 언급은 둘러싼 에이전트의 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:
실행 컨텍스트 스택이 비어 있으면 null을 반환한다.
ec를 실행 컨텍스트 스택의 최상단에서 ScriptOrModule 구성 요소가 null이 아닌 실행 컨텍스트로 둔다.
그러한 실행 컨텍스트가 없으면 null을 반환하고; 그렇지 않으면 ec의 ScriptOrModule을 반환한다.
ResolveBinding의 결과는 항상 [[ReferencedName]] 필드가 name인 Reference 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:
The abstract operation GetNewTarget takes no arguments and returns Object 또는 undefined. running execution context의 LexicalEnvironment를 사용하여 NewTarget 값을 결정한다. It performs the following steps when called:
The abstract operation GetGlobalObject takes no arguments and returns Object. 현재 running execution context가 사용하는 전역 객체를 반환한다. It performs the following steps when called:
scriptOrModule이 Script Record 또는 Module Record라면, ec를 실행 컨텍스트 스택의 최상단에서 ScriptOrModule 구성 요소가 scriptOrModule인 실행 컨텍스트로 둔다. ec의 Realm 구성 요소는 scriptOrModule.[[Realm]]이다.
어떤 특정 시점에, 다음 모든 조건이 참이면 실행은 ECMAScript 코드를 평가할 준비가 되었다(prepared to evaluate ECMAScript code)고 한다:
JobCallback Record { [[Callback]]: callback, [[HostDefined]]: empty }를 반환한다.
웹 브라우저가 아닌 ECMAScript 호스트는 HostMakeJobCallback의 기본 구현을 사용해야 한다.
Note
이는 콜백이 궁극적으로 스케줄되고 실행되도록 책임지는 함수에 콜백이 전달되는 시점에 호출된다. 예를 들어, promise.then(thenAction)은 반응 Job이 스케줄되는 시점이 아니라 Promise.prototype.then을 호출하는 시점에 thenAction에 대해 MakeJobCallback을 호출한다.
웹 브라우저가 아닌 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을 미래의 어느 시점에 수행하도록 스케줄한다. 이 알고리즘과 함께 사용되는 추상 클로저는 우선순위나 순서 같은 추가 제약 없이 스케줄되는 것을 의도한다.
The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (Job 추상 클로저) and realm (Realm Record 또는 null) and returns unused. job을 미래의 어느 시점에 수행하도록 스케줄한다. 이 알고리즘과 함께 사용되는 추상 클로저는 Promise 처리와 관련이 있거나 그렇지 않더라도 Promise 처리 연산과 동일한 우선순위로 스케줄되는 것을 의도한다.
HostEnqueuePromiseJob 구현은 9.5의 요구 사항과 아래 사항을 따라야 한다:
realm이 null이 아니면, job이 호출될 때마다 구현은 job 호출 시점에 실행이 ECMAScript 코드를 평가할 준비가 되도록 구현 정의 단계를 수행해야 한다.
HostEnqueuePromiseJob이 호출되는 시점에 scriptOrModule을 GetActiveScriptOrModule()으로 둔다. realm이 null이 아니면, job이 호출될 때마다 구현은 scriptOrModule이 job 호출 시점에 활성 스크립트 또는 모듈이 되도록 구현 정의 단계를 수행해야 한다.
잡은 그들을 스케줄한 HostEnqueuePromiseJob 호출과 동일한 순서로 실행되어야 한다.
The host-defined abstract operation HostEnqueueTimeoutJob takes arguments timeoutJob (Job 추상 클로저), realm (Realm Record), and milliseconds (음이 아닌 유한 Number) and returns unused. realm.[[AgentSignifier]]로 표시된 에이전트에서 realm 내에 timeoutJob을 최소 milliseconds 밀리초 후에 수행되도록 스케줄한다.
agent는 ECMAScript 실행 컨텍스트 집합, 실행 컨텍스트 스택, 실행 중 실행 컨텍스트(running execution context), Agent Record, 그리고 executing thread로 구성된다. executing thread를 제외한 구성 요소들은 오직 그 에이전트에만 속한다.
에이전트의 executing thread는 다른 에이전트와 독립적으로 그 에이전트의 실행 컨텍스트들에 대해 알고리즘 단계를 실행한다. 단, 여러 에이전트가 하나의 executing thread를 공유할 수 있는데, 그 공유하는 에이전트 중 어느 것도 Agent Record의 [[CanBlock]] 필드가 true이면 안 된다.
에이전트의 executing thread가 알고리즘 단계를 실행하는 동안, 그 에이전트는 그 단계들의 surrounding agent(둘러싼 에이전트)이다. 그 단계들은 둘러싼 에이전트를 사용하여 에이전트가 보유한 명세 수준 실행 객체—실행 중 실행 컨텍스트, 실행 컨텍스트 스택, Agent Record의 필드—에 접근한다.
agent signifier(에이전트 식별자)는 에이전트를 식별하기 위해 사용되는 전역적으로 고유한 불투명 값이다.
초기에는 새 빈 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) 접근의 (인지된) 원자성에 대해 아무것도 의미하지 않는다. 특히 비원자 접근은 여전히 여러 개의 별도 메모리 접근 시퀀스로 수행될 수 있다. 세부 사항은 ReadSharedMemory와 WriteSharedMemory 참조.
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:
AR.[[ModuleAsyncEvaluationCount]]를 count + 1로 설정한다.
count를 반환한다.
Note
이 값은 보류 중(pending) 모듈 사이의 상대적 평가 순서를 추적하기 위해서만 사용된다. 보류 중인 모듈이 없다면 구현은 관측 불가능하게 [[ModuleAsyncEvaluationCount]]를 0으로 재설정할 수 있다.
9.7 에이전트 클러스터(Agent Clusters)
agent cluster는 공유 메모리를 조작함으로써 통신할 수 있는 에이전트들의 최대 집합이다.
Note 1
서로 다른 에이전트 내의 프로그램들은 명시되지 않은 수단으로 메모리를 공유할 수 있다. 최소한 SharedArrayBuffers의 백업 메모리는 클러스터의 에이전트들 간에 공유될 수 있다.
메시지 전달로 통신할 수 있지만 메모리를 공유할 수 없는 에이전트들도 있을 수 있으며, 그들은 절대 같은 에이전트 클러스터에 속하지 않는다.
모든 에이전트는 정확히 하나의 에이전트 클러스터에 속한다.
Note 2
클러스터의 에이전트들이 어떤 특정 시점에 모두 살아 있을 필요는 없다. 에이전트 A가 다른 에이전트 B를 생성하고, 그 후 A가 종료되고 B가 에이전트 C를 생성한다면, A가 B와 일부 메모리를 공유할 수 있었고 B가 C와 일부 메모리를 공유할 수 있었다면 세 에이전트는 같은 클러스터에 속한다.
클러스터 내 모든 에이전트는 각각의 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 구현의 특정 실체에 대응할 필요가 없다.
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"라는 용어를 사용한다.
WeakRef.prototype.deref가 호출될 때, ( undefined 가 반환되지 않는 경우) 참조 대상(referent)은 이후의 동기적 접근에서 동일한 값을 반환할 수 있도록 살아 있게 유지된다. 이 목록(list)은 ClearKeptObjects 추상 연산을 사용해 동기 작업이 완료될 때 리셋된다.
일부 ECMAScript 구현에는 ECMAScript가 유휴(idle) 상태일 때를 포함해 백그라운드로 실행되는 가비지 컬렉터 구현이 포함되어 있다. 호스트 환경이 CleanupFinalizationRegistry를 스케줄하도록 하면, 구현이 파이널라이저 작업을 실행하기 위해 ECMAScript 실행을 재개하여 유지 중인 값을 해제함으로써 전체 메모리 사용량을 줄일 수 있다.
9.9.2 Liveness
객체 및/또는 심볼의 집합 S에 대해 hypothetical WeakRef-oblivious(가설적 WeakRef-무관) 실행이란, S의 요소인 참조 대상을 가진 WeakRef의 WeakRefDeref 추상 연산이 항상 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에 대한 어떤 유효한 미래의 가설적 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
어느 시점에서든 객체 및/또는 심볼 집합 S가 live가 아니라면, ECMAScript 구현은 다음 단계를 원자적으로 수행할 수 있다:
map.[[WeakMapData]]가 [[Key]]가 value인 Recordr을 포함하는 각 WeakMap map에 대해
r.[[Key]]를 empty로 설정한다.
r.[[Value]]를 empty로 설정한다.
set.[[WeakSetData]]가 value를 포함하는 각 WeakSet set에 대해
값이 value인 set.[[WeakSetData]]의 요소를 값이 empty인 요소로 교체한다.
Note 1
Liveness 정의와 함께, 본 절은 구현이 WeakRef에 관해 적용할 수 있는 최적화들을 규정한다.
객체의 정체성을 관측하지 않고 객체에 접근하는 것이 가능하다. 정체성이 관측되지 않는, escape하지 않는 객체의 프로퍼티에 대해 dead variable elimination, scalar replacement 같은 최적화는 허용된다. 그러한 최적화는 해당 객체를 가리키는 WeakRef들을 관측 가능하게 비울 수 있다.
반면 객체의 정체성이 관측 가능하고 그 객체가 WeakRef의 [[WeakRefTarget]] 내부 슬롯에 있다면, WeakRef를 관측 가능하게 비워 버리는 rematerialization 같은 최적화는 금지된다.
구현은 live가 아닌 객체나 심볼의 최대 집합에 대해 WeakRef를 반드시 비울 필요는 없다.
구현이 WeakRef를 비울 live가 아닌 집합 S를 선택한다면, 이 정의는 S 내 모든 값에 대한 WeakRef를 동시에 비우도록 요구한다. 즉, 값 v를 가리키는 WeakRef 하나를 비우면서, 비워지지 않았다면 v의 값을 관측할 수도 있는 다른 WeakRef를 비우지 않은 채 두는 것은 적합(conformant)하지 않다.
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:
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:
언어 정체성(language identity)이 없는 언어 값은 사전 참조 없이도 나타날 수 있으며 약한 참조로 사용하기에 부적합하다. Symbol.for로 생성된 Symbol 값은 다른 Symbol 값과 달리 언어 정체성이 없으므로 약한 참조로 사용하기에 부적합하다. Well-known symbols는 수집되지 않을 가능성이 높지만, 그 수가 제한되어 있고 다양한 구현 방식으로 관리 가능하므로 약한 참조로 사용하기에 적합한 것으로 간주된다. 그러나 live한 WeakMap 안의 well-known symbol에 연관된 어떤 값도 수집되지 않아 메모리 자원이 “누수”될 가능성이 있다.