Environment Record는 ECMAScript code의 lexical nesting structure에 기반하여 Identifier를 특정 variable 및 function과 associate하는 것을 define하는 데 사용되는 specification type입니다. 보통 Environment Record는 FunctionDeclaration, BlockStatement 또는 TryStatement의 Catch clause 같은 ECMAScript code의 특정 syntactic structure와 associated됩니다. 그러한 code가 evaluate될 때마다, 그 code가 생성하는 identifier binding을 record하기 위해 새 Environment Record가 생성됩니다.
모든 Environment Record는 [[OuterEnv]] field를 가지며, 이는 null이거나 outer Environment Record에 대한 reference입니다. 이는 Environment Record value의 logical nesting을 model하는 데 사용됩니다. (inner) Environment Record의 outer reference는 inner Environment Record를 logically surround하는 Environment Record에 대한 reference입니다. 물론 outer Environment Record는 자체 outer Environment Record를 가질 수 있습니다. 하나의 Environment Record가 여러 inner Environment Record의 outer environment 역할을 할 수 있습니다. 예를 들어, FunctionDeclaration이 두 개의 nested FunctionDeclaration을 포함하면, 각 nested function의 Environment Record는 surrounding function의 current evaluation의 Environment Record를 outer Environment Record로 갖게 됩니다.
Environment Record는 순수하게 specification mechanism이며 ECMAScript implementation의 특정 artefact에 대응할 필요가 없습니다. ECMAScript program이 이러한 value에 직접 access하거나 manipulate하는 것은 불가능합니다.
Function Environment Record는 ECMAScript function object의 invocation에 대응하며, 해당 function 안의 top-level declaration에 대한 binding을 포함합니다. 이는 새 this binding을 establish할 수 있습니다. 또한 super method invocation을 support하는 데 필요한 state를 capture합니다.
Global Environment Record는 Script global declaration에 사용됩니다. outer environment를 갖지 않으며, 그 [[OuterEnv]]는 null입니다. identifier binding으로 prepopulated될 수 있고, global environment의 identifier binding 중 일부를 제공하는 property를 가진 associated global object를 포함합니다. ECMAScript code가 execute됨에 따라, additional property가 global object에 added될 수 있고 initial property가 modified될 수 있습니다.
Environment Record abstract class는 Table 15에 정의된 abstract specification method를 포함합니다. 이러한 abstract method는 각 concrete subclass에 대해 distinct concrete algorithm을 가집니다.
The abstract method CreateMutableBinding takes arguments name (a String) and deletable (a Boolean) and returns either a normal completion containingunused or a throw completion.
Environment Record 안에 새롭지만 uninitialized인 mutable binding을 생성합니다. name은 bound name의 text입니다. deletable이 true이면 binding은 subsequently deleted될 수 있습니다.
The abstract method CreateImmutableBinding takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containingunused or a throw completion.
Environment Record 안에 새롭지만 uninitialized인 immutable binding을 생성합니다. name은 bound name의 text입니다. strict가 true이면 initialized된 후 이를 set하려는 attempt는 그 binding을 reference하는 operation의 strict mode setting과 관계없이 항상 exception을 throw합니다.
각 Declarative Environment Record는 variable, constant, let, class, module, import 및/또는 function declaration을 포함하는 ECMAScript program scope와 associated됩니다. Declarative Environment Record는 그 scope 안에 contained된 declaration이 정의하는 identifier의 set을 bind합니다.
The HasBinding concrete method of a Declarative Environment RecordenvRecord takes argument name (a String) and returns a normal completion containing a Boolean. argument identifier가 record에 의해 bound된 identifier 중 하나인지 determine합니다. It performs the following steps when called:
The CreateMutableBinding concrete method of a Declarative Environment RecordenvRecord takes arguments name (a String) and deletable (a Boolean) and returns a normal completion containingunused. uninitialized인 name name에 대한 새 mutable binding을 생성합니다. 이 Environment Record 안에는 name에 대한 binding이 already exist하지 않아야 합니다. deletable이 true이면, 새 binding은 deletion subject로 marked됩니다. It performs the following steps when called:
Assert: envRecord는 name에 대한 binding을 already have하지 않는다.
envRecord 안에 name에 대한 mutable binding을 생성하고 그것이 uninitialized임을 record한다. deletable이 true이면, newly created binding이 subsequent DeleteBinding call에 의해 deleted될 수 있음을 record한다.
unused를 반환한다.
9.1.1.1.3 CreateImmutableBinding ( name, strict )
The CreateImmutableBinding concrete method of a Declarative Environment RecordenvRecord takes arguments name (a String) and strict (a Boolean) and returns a normal completion containingunused. uninitialized인 name name에 대한 새 immutable binding을 생성합니다. 이 Environment Record 안에는 name에 대한 binding이 already exist하지 않아야 합니다. strict가 true이면, 새 binding은 strict binding으로 marked됩니다. It performs the following steps when called:
Assert: envRecord는 name에 대한 binding을 already have하지 않는다.
envRecord 안에 name에 대한 immutable binding을 생성하고 그것이 uninitialized임을 record한다. strict가 true이면, newly created binding이 strict binding임을 record한다.
The SetMutableBinding concrete method of a Declarative Environment RecordenvRecord takes arguments name (a String), value (an ECMAScript language value), and strict (a Boolean) and returns either a normal completion containingunused or a throw completion. name이 name인 identifier의 current binding의 bound value를 value value로 change하려고 attempt합니다. name에 대한 binding은 normally already exist하지만, rare case에는 그렇지 않을 수 있습니다. binding이 immutable binding이면 strict가 true일 때 TypeError가 thrown됩니다. It performs the following steps when called:
각 Object Environment Record는 그 binding object라고 불리는 object와 associated됩니다. Object Environment Record는 그 binding object의 property name에 직접 corresponding하는 string identifier name의 set을 bind합니다. IdentifierName form의 string이 아닌 property key는 bound identifier의 set에 포함되지 않습니다. own property와 inherited property는 [[Enumerable]] attribute의 setting과 관계없이 set에 포함됩니다. property는 object에서 dynamically added되고 deleted될 수 있으므로, Object Environment Record에 의해 bound된 identifier의 set은 property를 add하거나 delete하는 모든 operation의 side-effect로 potentially change될 수 있습니다. 그러한 side-effect의 결과로 created되는 binding은 corresponding property의 Writable attribute가 false이더라도 mutable binding으로 considered됩니다. Immutable binding은 Object Environment Record에는 존재하지 않습니다.
with statement(14.11)에 대해 created된 Object Environment Record는 function call에서 사용하기 위한 implicit this value로 그 binding object를 제공할 수 있습니다. 이 capability는 Boolean [[IsWithEnvironment]] field에 의해 controlled됩니다.
Object Environment Record는 Table 16에 listed된 additional state field를 가집니다.
The CreateMutableBinding concrete method of an Object Environment RecordenvRecord takes arguments name (a String) and deletable (a Boolean) and returns either a normal completion containingunused or a throw completion. Environment Record의 associated binding object 안에 name이라는 name의 property를 생성하고 이를 value undefined로 initialize합니다. deletable이 true이면, 새 property의 [[Configurable]] attribute는 true로 set됩니다. 그렇지 않으면 false로 set됩니다. It performs the following steps when called:
Normally envRecord는 name에 대한 binding을 가지지 않지만, 만약 가진다면 DefinePropertyOrThrow의 semantics는 existing binding이 replaced되거나 shadowed되게 하거나 abrupt completion을 returned하게 할 수 있습니다.
The SetMutableBinding concrete method of an Object Environment RecordenvRecord takes arguments name (a String), value (an ECMAScript language value), and strict (a Boolean) and returns either a normal completion containingunused or a throw completion. Environment Record의 associated binding object's property 중 name이 name인 것의 value를 value value로 set하려고 attempt합니다. name이라는 name의 property는 normally already exist하지만, 존재하지 않거나 현재 writable하지 않으면 error handling은 strict에 의해 determined됩니다. It performs the following steps when called:
bindingObj를 envRecord.[[BindingObject]]로 둔다.
stillExists를 ? HasProperty(bindingObj, name)으로 둔다.
The DeleteBinding concrete method of an Object Environment RecordenvRecord takes argument name (a String) and returns either a normal completion containing a Boolean or a throw completion. environment object의 property에 대응하고 [[Configurable]] attribute의 value가 true인 binding만 delete할 수 있습니다. It performs the following steps when called:
bindingObj를 envRecord.[[BindingObject]]로 둔다.
? bindingObj.[[Delete]](name)를 반환한다.
9.1.1.2.8 HasThisBinding ( )
The HasThisBinding concrete method of an Object Environment RecordenvRecord takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of an Object Environment RecordenvRecord takes no arguments and returns an Object or undefined. It performs the following steps when called:
Function Environment Record는 function의 top-level scope를 represent하는 데 사용되는 Declarative Environment Record이며, function이 ArrowFunction function이나 AsyncArrowFunction function이 아니면 this binding을 제공합니다. function이 ArrowFunction function이나 AsyncArrowFunction function이 아니고 super를 reference하면, 그 Function Environment Record는 function 내부에서 super method invocation을 수행하는 데 사용되는 state도 포함합니다.
Function Environment Record는 Table 17에 listed된 additional state field를 가집니다.
이 Environment Record가 [[Construct]] internal method에 의해 created되었다면, [[NewTarget]]은 [[Construct]]newTarget parameter의 value입니다. 그렇지 않으면 그 value는 undefined입니다.
The abstract operation GetSuperBase takes argument envRecord (a Function Environment Record) and returns an Object, null, or undefined. envRecord에 bound된 super property access의 base인 object를 반환합니다. value undefined는 그러한 access가 runtime error를 produce함을 나타냅니다. It performs the following steps when called:
home을 envRecord.[[FunctionObject]].[[HomeObject]]로 둔다.
Global Environment Record는 common realm에서 processed되는 모든 ECMAScript Script element가 shared하는 outer most scope를 represent하는 데 사용됩니다. Global Environment Record는 built-in global(clause 19), global object의 property, 그리고 Script 안에서 occur하는 모든 top-level declaration(8.2.11, 8.2.13)에 대한 binding을 제공합니다.
The CreateMutableBinding concrete method of a Global Environment RecordenvRecord takes arguments name (a String) and deletable (a Boolean) and returns either a normal completion containingunused or a throw completion. uninitialized인 name name에 대한 새 mutable binding을 생성합니다. binding은 associated DeclarativeRecord 안에 created됩니다. name에 대한 binding은 DeclarativeRecord 안에 already exist하지 않아야 합니다. deletable이 true이면, 새 binding은 deletion subject로 marked됩니다. It performs the following steps when called:
The CreateImmutableBinding concrete method of a Global Environment RecordenvRecord takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containingunused or a throw completion. uninitialized인 name name에 대한 새 immutable binding을 생성합니다. 이 Environment Record 안에는 name에 대한 binding이 already exist하지 않아야 합니다. strict가 true이면, 새 binding은 strict binding으로 marked됩니다. It performs the following steps when called:
The SetMutableBinding concrete method of a Global Environment RecordenvRecord takes arguments name (a String), value (an ECMAScript language value), and strict (a Boolean) and returns either a normal completion containingunused or a throw completion. name이 name인 identifier의 current binding의 bound value를 value value로 change하려고 attempt합니다. binding이 immutable binding이고 strict가 true이면, TypeError가 thrown됩니다. name이라는 binding은 normally already exist하지만, 존재하지 않거나 currently writable하지 않으면 error handling은 strict에 의해 determined됩니다. It performs the following steps when called:
The GetBindingValue concrete method of a Global Environment RecordenvRecord takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. name이 name인 bound identifier의 value를 반환합니다. binding이 uninitialized binding이면, ReferenceError exception을 throw합니다. name이라는 binding은 normally already exist하지만, 존재하지 않거나 currently writable하지 않으면 error handling은 strict에 의해 determined됩니다. It performs the following steps when called:
The HasThisBinding concrete method of a Global Environment RecordenvRecord takes no arguments and returns true. It performs the following steps when called:
The WithBaseObject concrete method of a Global Environment RecordenvRecord takes no arguments and returns undefined. It performs the following steps when called:
undefined를 반환한다.
9.1.1.4.12 HasLexicalDeclaration ( envRecord, name )
The abstract operation HasLexicalDeclaration takes arguments envRecord (a Global Environment Record) and name (a String) and returns a Boolean. argument identifier가 LexicalDeclaration 또는 ClassDeclaration 같은 lexical declaration을 사용하여 created된 envRecord 안의 binding을 가지는지 determine합니다. It performs the following steps when called:
var 또는 function declaration을 사용하여 declared된 것이 아니라 directly created된 property가 global object 위에 존재할 수 있습니다. global lexical binding은 global object의 non-configurable property와 같은 name으로 created될 수 없습니다. global property "undefined"는 그러한 property의 example입니다.
9.1.1.4.14 CanDeclareGlobalVar ( envRecord, name )
The abstract operation CanDeclareGlobalVar takes arguments envRecord (a Global Environment Record) and name (a String) and returns either a normal completion containing a Boolean or a throw completion. same argument name에 대해 corresponding CreateGlobalVarBinding call이 called된다면 succeed할지 determine합니다. Redundant var declaration과 pre-existing global object property에 대한 var declaration은 allowed됩니다. It performs the following steps when called:
The abstract operation CreateGlobalVarBinding takes arguments envRecord (a Global Environment Record), name (a String), and deletable (a Boolean) and returns either a normal completion containingunused or a throw completion. associated Object Environment Record 안에 mutable binding을 create하고 initialize합니다. binding이 already exist하면, 재사용되며 initialized된 것으로 assumed됩니다. It performs the following steps when called:
Global function declaration은 항상 global object의 own property로 represented됩니다. 가능하면, existing own property는 standard set of attribute values를 가지도록 reconfigured됩니다. Step 7은 InitializeBinding concrete method를 calling하는 것이 수행할 것과 equivalent하며 globalObj가 Proxy이면 같은 sequence의 Proxy trap call을 produce합니다.
9.1.1.5 Module Environment Records
Module Environment Record는 ECMAScript Module의 outer scope를 represent하는 데 사용되는 Declarative Environment Record입니다. normal mutable 및 immutable binding에 더해, Module Environment Record는 다른 Environment Record에 존재하는 target binding에 대한 indirect access를 제공하는 binding인 immutable import binding도 제공합니다.
The GetBindingValue concrete method of a Module Environment RecordenvRecord takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. name이 name인 bound identifier의 value를 반환합니다. 그러나 binding이 indirect binding이면 target binding의 value가 returned됩니다. binding이 존재하지만 uninitialized이면 ReferenceError가 thrown됩니다. It performs the following steps when called:
The HasThisBinding concrete method of a Module Environment RecordenvRecord takes no arguments and returns true. It performs the following steps when called:
The abstract operation CreateImportBinding takes arguments envRecord (a Module Environment Record), name (a String), targetModule (a Module Record), and targetName (a String) and returns unused. name name에 대한 새 initialized immutable indirect binding을 생성합니다. envRecord 안에는 name에 대한 binding이 already exist하지 않아야 합니다. targetName은 targetModule의 Module Environment Record에 존재하는 binding의 name입니다. 새 binding의 value에 대한 access는 target binding의 bound value에 indirectly access합니다. It performs the following steps when called:
Assert: envRecord는 name에 대한 binding을 already have하지 않는다.
Assert: targetModule.[[Environment]]가 instantiated되면, 이는 targetName에 대한 direct binding을 가질 것이다.
envRecord 안에 targetModule과 targetName을 target binding으로 reference하는 name에 대한 immutable indirect binding을 생성하고, 그 binding이 initialized되었음을 record한다.
The abstract operation NewDeclarativeEnvironment takes argument outerEnv (an Environment Record or null) and returns a Declarative Environment Record. It performs the following steps when called:
The abstract operation NewObjectEnvironment takes arguments obj (an Object), isWithEnv (a Boolean), and outerEnv (an Environment Record or null) and returns an Object Environment Record. It performs the following steps when called:
The abstract operation NewFunctionEnvironment takes arguments func (an ECMAScript function object) and newTarget (an Object or undefined) and returns a Function Environment Record. It performs the following steps when called:
envRecord.[[DisposableResourceStack]]을 새 빈 List로 설정한다.
envRecord를 반환한다.
9.1.2.5 NewGlobalEnvironment ( obj, thisValue )
The abstract operation NewGlobalEnvironment takes arguments obj (an Object) and thisValue (an Object) and returns a Global Environment Record. It performs the following steps when called:
The abstract operation ResolvePrivateIdentifier takes arguments privateEnv (a PrivateEnvironment Record) and identifier (a String) and returns a Private Name. It performs the following steps when called:
evaluate되기 전에, 모든 ECMAScript code는 realm과 associated되어야 합니다. Conceptually, realm은 intrinsic object의 set, ECMAScript global environment, 그 global environment의 scope 안에 loaded된 모든 ECMAScript code, 그리고 기타 associated state와 resource로 구성됩니다.
realm은 이 명세에서 Table 20에 specified된 field를 가진 Realm Record로 represented됩니다:
Realm Record와 additional information을 associate해야 하는 host가 사용하기 위해 reserved된 field입니다.
9.3.1 InitializeHostDefinedRealm ( )
The abstract operation InitializeHostDefinedRealm takes no arguments and returns either a normal completion containingunused or a throw completion. It performs the following steps when called:
realmRecord.[[Intrinsics]]의 field를 Table 6에 listed된 value로 설정한다. field name은 table의 “Intrinsic Name” column에 listed된 name입니다. 각 field의 value는 clause 19부터 28까지의 각 object specification에 의해 정의된 property value로 fully and recursively populated된 새 object value입니다. 모든 object property value는 newly created object value입니다. built-in function object인 모든 value는 CreateBuiltinFunction(steps, length, name, slots, realmRecord, proto, async)를 수행하여 created되며, 여기서 steps는 이 명세가 제공하는 해당 function의 definition, name은 function의 "name" property의 initial value, length는 function의 "length" property의 initial value, slots는 function의 specified internal slot의 name list(있는 경우), proto는 function의 [[Prototype]] internal slot의 specified value, async는 function이 “async”로 described되면 true이고 그렇지 않으면 false입니다. intrinsics와 그 property의 creation은 아직 created되지 않은 object에 대한 dependency를 피하도록 ordered되어야 합니다.
propertyDesc를 property에 대한 specified attribute를 contain하는, property에 대한 fully populated data Property Descriptor로 둔다. 19.2, 19.3 또는 19.4에 listed된 property에 대해서는 [[Value]] attribute의 value가 realmRecord의 corresponding intrinsic object입니다.
execution context는 ECMAScript implementation에 의한 code의 runtime evaluation을 track하는 데 사용되는 specification device입니다. 어느 시점에서든, 실제로 code를 executing하고 있는 execution context는 agent마다 at most one입니다. 이는 agent의 running execution context로 알려져 있습니다. 이 명세에서 running execution context에 대한 모든 reference는 surrounding agent의 running execution context를 denote합니다.
execution context stack은 execution context를 track하는 데 사용됩니다. running execution context는 항상 이 stack의 top element입니다. currently running execution context와 associated된 executable code에서 그 execution context와 associated되지 않은 executable code로 control이 transferred될 때마다 새 execution context가 created됩니다. newly created execution context는 stack 위로 pushed되고 running execution context가 됩니다.
execution context는 associated code의 execution progress를 track하는 데 필요한 implementation specific state를 포함합니다. 각 execution context는 적어도 Table 21에 listed된 state component를 가집니다.
Table 21: State Components for All Execution Contexts
Component
Purpose
code evaluation state
이 execution context와 associated된 code의 evaluation을 perform, suspend, resume하는 데 필요한 모든 state입니다.
실행 중인 실행 컨텍스트에 의한 코드 평가는 이 명세 안에 정의된 여러 지점에서 중단될 수 있다. 실행 중인 실행 컨텍스트가 일단 중단되면, 다른 실행 컨텍스트가 실행 중인 실행 컨텍스트가 되어 그 코드를 평가하기 시작할 수 있다. 나중의 어느 시점에 중단된 실행 컨텍스트가 다시 실행 중인 실행 컨텍스트가 되어 이전에 중단되었던 지점에서 그 코드 평가를 계속할 수 있다. 실행 컨텍스트들 사이에서 실행 중인 실행 컨텍스트 상태의 전환은 보통 스택과 같은 후입선출 방식으로 일어난다. 그러나 일부 ECMAScript 기능은 실행 중인 실행 컨텍스트의 비-LIFO 전환을 필요로 한다.
실행 중인 실행 컨텍스트의 Realm 구성 요소 값은 현재 Realm Record라고도 한다. 실행 중인 실행 컨텍스트의 Function 구성 요소 값은 활성 함수 객체라고도 한다.
ECMAScript 코드 실행 컨텍스트에는 Table 22에 나열된 추가 상태 구성 요소가 있다.
Table 22: Additional State Components for ECMAScript Code Execution Contexts
execution context는 순수하게 specification mechanism이며 ECMAScript implementation의 특정 artefact에 대응할 필요가 없습니다. ECMAScript code가 execution context에 직접 access하거나 observe하는 것은 불가능합니다.
9.4.1 GetActiveScriptOrModule ( )
The abstract operation GetActiveScriptOrModule takes no arguments and returns a Script Record, a Module Record, or null. running execution context에 기반하여 running script 또는 module을 determine하는 데 사용됩니다. It performs the following steps when called:
The abstract operation ResolveBinding takes argument name (a String) and optional argument envRecord (an Environment Record or undefined) and returns either a normal completion containing a Reference Record or a throw completion. name의 binding을 determine하는 데 사용됩니다. envRecord는 binding을 search할 Environment Record를 명시적으로 provide하는 데 사용될 수 있습니다. It performs the following steps when called:
envRecord가 present하지 않거나 envRecord가 undefined이면, 다음을 수행한다.
ResolveBinding의 result는 항상 [[ReferencedName]] field가 name인 Reference Record입니다.
9.4.3 GetThisEnvironment ( )
The abstract operation GetThisEnvironment takes no arguments and returns an Environment Record. keywordthis의 binding을 currently supply하는 Environment Record를 찾습니다. It performs the following steps when called:
The abstract operation GetNewTarget takes no arguments and returns an Object or undefined. running execution context의 LexicalEnvironment를 사용하여 NewTarget value를 determine합니다. It performs the following steps when called:
The abstract operation GetGlobalObject takes no arguments and returns an Object. currently running execution context가 사용하는 global object를 반환합니다. It performs the following steps when called:
The abstract operation RunCallerContext takes argument value (ECMAScript 언어 값 또는 empty) and returns Completion Record. 호출자 컨텍스트를 재개하고(value를 재개 값으로 보냄), 결과가 있으면 그 결과를 기다린다. It performs the following steps when called:
genContext를 실행 중인 실행 컨텍스트라 하자.
실행 컨텍스트 스택에서 genContext를 제거하고, 실행 컨텍스트 스택의 맨 위에 있는 실행 컨텍스트를 실행 중인 실행 컨텍스트로 복원한다.
Host environment는 scheduling과 관련하여 Job을 uniformly 취급할 필요가 없습니다. 예를 들어, web browser와 Node.js는 Promise-handling Job을 다른 work보다 higher priority로 취급합니다. future feature는 그렇게 high priority로 취급되지 않는 Job을 add할 수 있습니다.
특정 시점에서 scriptOrModule(Script Record, Module Record 또는 null)은 다음 조건이 모두 true이면 active script or module입니다:
HostMakeJobCallback의 default implementation은 called될 때 다음 step을 수행합니다:
JobCallback Record { [[Callback]]: callback, [[HostDefined]]: empty }를 반환한다.
web browser가 아닌 ECMAScript host는 HostMakeJobCallback의 default implementation을 사용해야 합니다.
Note
이는 callback이 eventually scheduled되고 run되는 것을 responsible하는 function에 passed되는 시점에 called됩니다. 예를 들어, promise.then(thenAction)은 reaction Job을 scheduling하는 시점이 아니라 Promise.prototype.then을 invoking하는 시점에 thenAction에 대해 MakeJobCallback을 call합니다.
web browser가 아닌 ECMAScript host는 HostCallJobCallback의 default implementation을 사용해야 합니다.
9.5.4 HostEnqueueGenericJob ( job, realm )
The host-defined abstract operation HostEnqueueGenericJob takes arguments job (a JobAbstract Closure) and realm (a Realm Record) and returns unused. realm.[[AgentSignifier]]가 signified하는 agent 안에서, realmrealm 안에 job을 future time에 performed되도록 schedule합니다. 이 algorithm과 함께 사용되는 Abstract Closure는 priority와 ordering 같은 additional constraint 없이 scheduled되도록 intended됩니다.
The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (a JobAbstract Closure) and realm (a Realm Record or null) and returns unused. job을 future time에 performed되도록 schedule합니다. 이 algorithm과 함께 사용되는 Abstract Closure는 Promise의 handling과 관련되거나, 그 밖에 Promise handling operation과 equal priority로 scheduled되도록 intended됩니다.
HostEnqueuePromiseJob의 implementation은 9.5의 requirement와 다음 requirement를 conform해야 합니다:
realm이 null이 아니면, job이 invoked될 때마다 implementation은 job의 invocation 시점에 execution이 ECMAScript code를 evaluate할 준비가 되도록 implementation-defined step을 수행해야 합니다.
The host-defined abstract operation HostEnqueueTimeoutJob takes arguments timeoutJob (a JobAbstract Closure), realm (a Realm Record), and milliseconds (a non-negative finite Number) and returns unused. realm.[[AgentSignifier]]가 signified하는 agent 안에서, realmrealm 안에 timeoutJob을 at least milliseconds milliseconds 후에 performed되도록 schedule합니다.
[[IsLockFree1]], [[IsLockFree2]], [[IsLockFree8]]의 value는 necessarily hardware에 의해 determined되는 것은 아니며, over time 및 ECMAScript implementation 사이에서 vary할 수 있는 implementation choice를 reflect할 수도 있습니다.
[[IsLockFree4]] field는 없습니다: 4-byte atomic operation은 항상 lock-free입니다.
실제로 atomic operation이 어떤 type의 lock으로 implement되면 그 operation은 lock-free가 아닙니다. Lock-free는 wait-free를 imply하지 않습니다: lock-free atomic operation을 complete하는 데 필요한 machine step 수에는 upper bound가 없습니다.
size가 n인 atomic access가 lock-free라는 것이 size가 n인 non-atomic access의 (perceived) atomicity에 대해 어떤 것도 imply하지 않습니다. 특히 non-atomic access는 여전히 여러 separate memory access의 sequence로 performed될 수 있습니다. detail은 ReadSharedMemory와 WriteSharedMemory를 참조하십시오.
Note 3
agent는 specification mechanism이며 ECMAScript implementation의 특정 artefact에 대응할 필요가 없습니다.
9.6.1 AgentSignifier ( )
The abstract operation AgentSignifier takes no arguments and returns an agent signifier. It performs the following steps when called:
일부 environment에서는 주어진 agent가 suspend되는 것이 reasonable하지 않을 수 있습니다. 예를 들어, web browser environment에서는 document의 main event handling thread가 suspend되는 것을 disallow하면서 worker의 event handling thread는 suspend하도록 allow하는 것이 reasonable할 수 있습니다.
9.6.3 IncrementModuleAsyncEvaluationCount ( )
The abstract operation IncrementModuleAsyncEvaluationCount takes no arguments and returns a non-negative integer. It performs the following steps when called:
count를 agentRecord.[[ModuleAsyncEvaluationCount]]로 둔다.
agentRecord.[[ModuleAsyncEvaluationCount]]를 count + 1로 설정한다.
count를 반환한다.
Note
이 value는 pending module 사이의 relative evaluation order를 keep track하는 데만 사용됩니다. implementation은 pending module이 없을 때마다 unobservably [[ModuleAsyncEvaluationCount]]를 0으로 reset할 수 있습니다.
9.7 Agent Clusters
agent cluster는 shared memory를 operate함으로써 communicate할 수 있는 agent의 maximal set입니다.
Note 1
서로 다른 agent 안의 program은 unspecified means로 memory를 share할 수 있습니다. 최소한 SharedArrayBuffer의 backing memory는 cluster 안의 agent들 사이에서 shared될 수 있습니다.
message passing으로 communicate할 수 있지만 memory를 share할 수 없는 agent가 있을 수 있습니다. 이들은 결코 같은 agent cluster에 있지 않습니다.
cluster 안의 agent가 모두 특정 시점에 alive일 필요는 없습니다. agentA가 다른 agentB를 create한 후 A가 terminate되고 B가 agentC를 create하면, A가 B와 some memory를 share할 수 있었고 B가 C와 some memory를 share할 수 있었다면 세 agent는 같은 cluster에 있습니다.
cluster 안의 모든 agent는 각각의 Agent Record 안의 [[LittleEndian]] field에 대해 같은 value를 가져야 합니다.
Note 3
agent cluster 안의 서로 다른 agent가 [[LittleEndian]]의 different value를 가지면 multi-byte data에 shared memory를 use하기 어려워집니다.
cluster 안의 모든 agent는 각각의 Agent Record 안의 [[IsLockFree1]] field에 대해 같은 value를 가져야 합니다; [[IsLockFree2]]와 [[IsLockFree8]] field도 마찬가지입니다.
cluster 안의 모든 agent는 각각의 Agent Record 안의 [[Signifier]] field에 대해 서로 다른 value를 가져야 합니다.
embedding은 agent의 knowledge나 cooperation 없이 agent를 deactivate(forward progress를 stop)하거나 activate(forward progress를 resume)할 수 있습니다. embedding이 그렇게 하는 경우, cluster 안의 일부 agent를 active로 남겨둔 채 다른 agent를 indefinitely deactivated 상태로 두어서는 안 됩니다.
Note 4
preceding restriction의 purpose는 다른 agent가 deactivated되어 agent가 deadlock되거나 starve되는 situation을 avoid하는 것입니다. 예를 들어, 어떤 window의 document와 independent한 lifetime을 가진 HTML shared worker가 그러한 independent document의 dedicated worker와 memory를 share할 수 있도록 allowed되었고, document와 그 dedicated worker가 dedicated worker가 lock을 hold하고 있는 동안 deactivated된다면(예: document가 window의 history에 pushed됨), shared worker가 그 lock을 acquire하려고 할 때 shared worker는 dedicated worker가 다시 activated될 때까지, 혹은 ever, blocked됩니다. Meanwhile 다른 window에서 shared worker에 access하려는 다른 worker는 starve됩니다.
restriction의 implication은 embedding 안에서 같은 suspend/wake collective에 belong하지 않는 agent 사이에서는 memory를 share할 수 없다는 것입니다.
embedding은 agent cluster의 다른 agent가 prior knowledge나 cooperation을 가지지 않아도 agent를 terminate할 수 있습니다. agent가 cluster 안의 자체 programmatic action이나 다른 agent의 programmatic action이 아니라 cluster 외부의 force에 의해 terminated되면, embedding은 두 strategy 중 하나를 choose해야 합니다: cluster 안의 모든 agent를 terminate하거나, cluster 안의 agent가 coordinate하여 cluster의 적어도 하나의 remaining member가 termination을 detect할 수 있게 하는 reliable API를 provide해야 하며, termination data는 terminated된 agent를 identify하기에 충분한 information을 contain해야 합니다.
Note 5
그 type의 termination example은 다음과 같습니다: operating system 또는 user가 separate process에서 running 중인 agent를 terminate하는 경우; per-agent resource accounting이 agent가 runaway임을 indicate할 때 embedding 자체가 다른 agent와 in-process로 running 중인 agent를 terminate하는 경우.
다음 specification value 각각과, 그것들로부터 transitively reachable한 value는 exactly one agent cluster에 belong합니다.
이는 memory model의 liveness guarantee와 함께, 모든 seq-cst write가 eventually 모든 agent에 observable하게 됨을 ensure합니다.
9.9 Processing Model of WeakRef and FinalizationRegistry Targets
9.9.1 Objectives
이 명세는 어떤 object 또는 symbol도 garbage collected될 것이라는 guarantee를 하지 않습니다. live가 아닌 object 또는 symbol은 long period of time 후에 released될 수도 있고, 전혀 released되지 않을 수도 있습니다. 이러한 이유로, 이 명세는 garbage collection에 의해 triggered되는 behaviour를 describing할 때 “may”라는 term을 사용합니다.
WeakRef.prototype.deref가 called될 때, referent(undefined가 returned되지 않는 경우)는 subsequent synchronous access도 같은 value를 return하도록 alive로 kept됩니다. 이 list는 ClearKeptObjects abstract operation을 사용하여 synchronous work가 done될 때 reset됩니다.
일부 ECMAScript implementation은 ECMAScript가 idle일 때를 포함하여 background에서 run하는 garbage collector implementation을 포함합니다. host environment가 CleanupFinalizationRegistry를 schedule하게 하면 finalizer work를 run하기 위해 ECMAScript execution을 resume할 수 있으며, 이는 held value를 free up하여 overall memory usage를 reduce할 수 있습니다.
9.9.2 Liveness
object 및/또는 symbol의 어떤 set objSet에 대해 objSet와 관련한 hypothetical WeakRef-oblivious execution은 referent가 objSet의 element인 WeakRef의 abstract operation WeakRefDeref가 항상 undefined를 반환하는 execution입니다.
Note 1
WeakRef-obliviousness는 liveness와 함께 두 notion을 capture합니다. 첫째, WeakRef 자체는 그 referent를 alive로 keep하지 않습니다. 둘째, liveness의 cycle은 value가 live임을 imply하지 않습니다. 구체적으로, v의 liveness를 determining하는 것이 WeakRef referent r의 liveness를 determining하는 것에 depend한다면, r의 liveness는 v의 liveness를 assume할 수 없습니다. 이는 circular reasoning이기 때문입니다.
Note 2
WeakRef-obliviousness는 cycle을 account하기 위해 individual value 대신 object 또는 symbol의 set에 대해 정의됩니다. individual value에 대해 정의된다면, cycle 안의 WeakRef referent는 그 identity가 cycle 안의 다른 WeakRef referent를 통해서만 observed되더라도 live로 considered될 것입니다.
Note 3
Colloquially, 우리는 individual object 또는 symbol이 그것을 contain하는 모든 set이 live이면 live라고 말합니다.
evaluation 중 어느 point에서든, object 및/또는 symbol의 set objSet는 다음 조건 중 하나가 met되면 live로 considered됩니다:
objSet 안의 어떤 element가 어떤 agent의 [[KeptAlive]]List에 included되어 있습니다.
objSet와 관련하여 valid future hypothetical WeakRef-oblivious execution이 존재하며, 이는 objSet 안의 어떤 value의 identity를 observe합니다.
Note 4
위의 두 번째 condition은 value의 identity가 non-WeakRef means를 통해 observable하면 그 value가 live라는 intuition을 capture하려는 의도입니다. value의 identity는 strict equality comparison을 observing하거나 Map의 key로 사용되는 value를 observing함으로써 observed될 수 있습니다.
Note 5
field, internal slot 또는 property 안에 object나 symbol이 존재한다는 것은 그 value가 live임을 imply하지 않습니다. 예를 들어 해당 value가 program에 다시 passed되지 않으면, it cannot be observed.
이는 WeakMap의 key, WeakSet의 member, 그리고 FinalizationRegistry Cell record의 [[WeakRefTarget]] 및 [[UnregisterToken]] field의 경우에 해당합니다.
위 definition은, WeakMap 안의 key가 live가 아니면, 그 corresponding value도 necessarily live인 것은 아님을 imply합니다.
Note 6
Liveness는 engine이 반드시 empty하지 않아야 하는 WeakRef를 guarantee하기 위한 lower bound입니다. 여기서 정의된 Liveness는 undecidable입니다. 실제로 engine은 reachability 같은 conservative approximation을 사용합니다. significant implementation leeway가 expected됩니다.
9.9.3 Execution
어느 때든 object 및/또는 symbol의 set objSet가 live가 아니면, ECMAScript implementation은 다음 step을 atomically perform할 수 있습니다:
objSet의 각 element value에 대해, 다음을 수행한다.
ref.[[WeakRefTarget]]이 value인 각 WeakRefref에 대해, 다음을 수행한다.
ref.[[WeakRefTarget]]를 empty로 설정한다.
finalizationRegistry.[[Cells]]가 cell.[[WeakRefTarget]]이 value인 Recordcell을 contain하는 각 FinalizationRegistryfinalizationRegistry에 대해, 다음을 수행한다.
map.[[WeakMapData]]가 entry.[[Key]]가 value인 Recordentry를 contain하는 각 WeakMap map에 대해, 다음을 수행한다.
entry.[[Key]]를 empty로 설정한다.
entry.[[Value]]를 empty로 설정한다.
set.[[WeakSetData]]가 value를 contain하는 각 WeakSet set에 대해, 다음을 수행한다.
set.[[WeakSetData]] 안에서 value가 value인 element를 value가 empty인 element로 replace한다.
Note 1
liveness의 definition과 함께, 이 clause는 implementation이 WeakRef와 관련하여 apply할 수 있는 optimization을 prescribe합니다.
object의 identity를 observing하지 않고 object에 access하는 것이 가능합니다. identity가 observed되지 않는 non-escaping object의 property에 대한 dead variable elimination 및 scalar replacement 같은 optimization은 allowed됩니다. 따라서 이러한 optimization은 그러한 object를 point하는 WeakRef를 observably empty하는 것을 allow합니다.
반면, object의 identity가 observable이고 그 object가 WeakRef의 [[WeakRefTarget]] internal slot 안에 있으면, WeakRef를 observably empty하는 rematerialization 같은 optimization은 prohibited됩니다.
implementation은 non-live object 또는 symbol의 maximal set에 대해 WeakRef를 empty할 의무가 없습니다.
implementation이 WeakRef를 empty할 non-live set objSet을 choose하면, 이 definition은 objSet 안의 모든 value에 대한 WeakRef를 simultaneously empty할 것을 require합니다. 다시 말해, implementation이 value v를 point하는 WeakRef를 empty하면서, empty하지 않으면 v의 value를 observe하는 execution을 result할 수 있는 다른 WeakRef를 empty하지 않는 것은 conformant하지 않습니다.
The host-defined abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument finalizationRegistry (a FinalizationRegistry) and returns unused.
cleanupJob을 parameter가 없고 finalizationRegistry를 capture하며 called될 때 다음 step을 수행하는 새 JobAbstract Closure로 둔다:
The abstract operation ClearKeptObjects takes no arguments and returns unused. ECMAScript implementation은 synchronous sequence of ECMAScript executions가 completes될 때 ClearKeptObjects를 call할 것으로 expected됩니다. It performs the following steps when called:
abstract operation AddToKeptObjects가 target object 또는 symbol과 함께 called되면, 이는 ClearKeptObjects가 called될 때까지 target을 strongly point할 list에 target을 add합니다.
The abstract operation CanBeHeldWeakly takes argument arg (an ECMAScript language value) and returns a Boolean. arg가 weak reference로 사용하기에 suitable하면 and only if true를 반환합니다. weak reference로 사용하기에 suitable한 value만 WeakMap의 key, WeakSet의 element, WeakRef의 target, 또는 FinalizationRegistry의 target 중 하나일 수 있습니다. It performs the following steps when called:
language identity가 없는 language value는 prior reference 없이 manifested될 수 있으므로 weak reference로 사용하기에 unsuitable합니다. Symbol.for가 produced한 Symbol value는 다른 Symbol value와 달리 language identity를 가지지 않으며 weak reference로 사용하기에 unsuitable합니다. Well-known symbols는 collected되지 않을 가능성이 높지만, number가 limited되어 다양한 implementation approach로 manageable하기 때문에 nonetheless weak reference로 사용하기에 suitable한 것으로 treated됩니다. 그러나 live WeakMap 안의 well-known symbol에 associated된 value는 collected될 가능성이 낮고 implementation에서 memory resource를 “leak”할 수 있습니다.