16 ECMAScript 언어: 스크립트와 모듈

16.1 스크립트

구문

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return]

16.1.1 정적 의미론: 조기 오류

Script : ScriptBody
  • ScriptBody의 LexicallyDeclaredNames가 중복 항목을 포함하면 구문 오류이다.
  • ScriptBody의 LexicallyDeclaredNames의 어떤 요소가 ScriptBody의 VarDeclaredNames에도 나타나면 구문 오류이다.
ScriptBody : StatementList
  • super를 포함한 소스 텍스트가 직접 eval에 의해 처리되는 eval 코드가 아닌 한, StatementListsuper를 포함하면 구문 오류이다. 직접 eval 내의 super에 대한 추가 조기 오류 규칙은 19.2.1.1에 정의되어 있다.
  • NewTarget을 포함한 소스 텍스트가 직접 eval에 의해 처리되는 eval 코드가 아닌 한, StatementListNewTarget을 포함하면 구문 오류이다. 직접 eval에서 NewTarget에 대한 추가 조기 오류 규칙은 19.2.1.1에 정의되어 있다.
  • 인수 « »를 사용한 StatementList의 ContainsDuplicateLabels가 true이면 구문 오류이다.
  • 인수 « »를 사용한 StatementList의 ContainsUndefinedBreakTarget이 true이면 구문 오류이다.
  • 인수 « »와 « »를 사용한 StatementList의 ContainsUndefinedContinueTarget이 true이면 구문 오류이다.
  • ScriptBody를 포함한 소스 텍스트가 직접 eval에 의해 처리되는 eval 코드가 아닌 한, 인수 « »를 사용한 StatementList의 AllPrivateIdentifiersValid가 false이면 구문 오류이다.

16.1.2 정적 의미론: ScriptIsStrict : Boolean

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

Script : ScriptBodyopt
  1. ScriptBody가 존재하고 ScriptBodyDirective PrologueUse Strict Directive를 포함하면 true를 반환하고, 그렇지 않으면 false를 반환한다.

16.1.3 런타임 의미론: 평가

Script : [empty]
  1. undefined를 반환한다.

16.1.4 스크립트 레코드

스크립트 레코드는 평가되는 스크립트에 대한 정보를 캡슐화한다. 각 스크립트 레코드Table 37에 나열된 필드를 포함한다.

Table 37: 스크립트 레코드 필드
필드 이름 값 타입 의미
[[Realm]] Realm Record 이 스크립트가 생성된 영역.
[[ECMAScriptCode]] Script Parse Node 이 스크립트의 소스 텍스트를 파싱한 결과.
[[LoadedModules]] LoadedModuleRequest Records의 리스트 이 스크립트가 가져온 지정자 문자열에서 해결된 Module Record로의 맵. 리스트는 ModuleRequestsEqual(r1, r2)이 true인 서로 다른 Records r1r2를 두 개 포함하지 않는다.
[[HostDefined]] anything (기본값은 empty) 스크립트와 추가 정보를 연결해야 하는 호스트 환경에서 사용하기 위해 예약된 필드.

16.1.5 ParseScript ( sourceText, realm, hostDefined )

The abstract operation ParseScript takes arguments sourceText (ECMAScript 소스 텍스트), realm (Realm Record), and hostDefined (anything) and returns Script Record 또는 SyntaxError 객체의 비어있지 않은 리스트. It performs the following steps when called:

  1. script를 ParseText(sourceText, Script)로 둔다.
  2. script가 오류의 리스트이면 script를 반환한다.
  3. Script Record { [[Realm]]: realm, [[ECMAScriptCode]]: script, [[LoadedModules]]: « », [[HostDefined]]: hostDefined }를 반환한다.
Note

구현은 해당 스크립트 소스 텍스트에 대해 ParseScript를 평가하기 전에 스크립트 소스 텍스트를 파싱하고 조기 오류 조건을 분석할 수 있다. 그러나 오류 보고는 이 명세가 실제로 해당 소스 텍스트에 대해 ParseScript를 수행하는 시점까지 연기되어야 한다.

16.1.6 ScriptEvaluation ( scriptRecord )

The abstract operation ScriptEvaluation takes argument scriptRecord (Script Record) and returns ECMAScript 언어 값을 포함하는 정상 완료 또는 abrupt completion. It performs the following steps when called:

  1. globalEnvscriptRecord.[[Realm]].[[GlobalEnv]]로 둔다.
  2. scriptContext를 새로운 ECMAScript 코드 실행 컨텍스트로 둔다.
  3. scriptContext의 Function을 null로 설정한다.
  4. scriptContextRealmscriptRecord.[[Realm]]으로 설정한다.
  5. scriptContext의 ScriptOrModule을 scriptRecord로 설정한다.
  6. scriptContext의 VariableEnvironment를 globalEnv로 설정한다.
  7. scriptContext의 LexicalEnvironment를 globalEnv로 설정한다.
  8. scriptContext의 PrivateEnvironment를 null로 설정한다.
  9. 실행 중인 실행 컨텍스트를 일시 중단한다.
  10. scriptContext를 실행 컨텍스트 스택에 푸시한다; scriptContext가 이제 실행 중인 실행 컨텍스트이다.
  11. scriptscriptRecord.[[ECMAScriptCode]]로 둔다.
  12. resultCompletion(GlobalDeclarationInstantiation(script, globalEnv))로 둔다.
  13. result가 정상 완료이면
    1. resultCompletion(Evaluation of script)로 설정한다.
    2. result가 정상 완료이고 result.[[Value]]empty이면
      1. resultNormalCompletion(undefined)로 설정한다.
  14. scriptContext를 일시 중단하고 실행 컨텍스트 스택에서 제거한다.
  15. 단언: 실행 컨텍스트 스택이 비어있지 않다.
  16. 이제 실행 컨텍스트 스택의 맨 위에 있는 컨텍스트를 실행 중인 실행 컨텍스트로 재개한다.
  17. result를 반환한다.

16.1.7 GlobalDeclarationInstantiation ( script, env )

The abstract operation GlobalDeclarationInstantiation takes arguments script (Script Parse Node) and env (Global Environment Record) and returns unused를 포함하는 정상 완료 또는 throw completion.

Note 1

스크립트 평가를 위한 실행 컨텍스트가 설정될 때, 선언은 현재 전역 환경에서 인스턴스화된다. 코드에서 선언된 각 전역 바인딩이 인스턴스화된다.

호출될 때 다음 단계를 수행한다:

  1. lexNamesscript의 LexicallyDeclaredNames로 둔다.
  2. varNamesscript의 VarDeclaredNames로 둔다.
  3. lexNames의 각 요소 name에 대해
    1. HasLexicalDeclaration(env, name)이 true이면 SyntaxError 예외를 던진다.
    2. hasRestrictedGlobal을 ? HasRestrictedGlobalProperty(env, name)로 둔다.
    3. 참고: 전역 varfunction 바인딩(비-strict 직접 eval에 의해 도입된 것들을 제외하고)은 non-configurable이므로 제한된 전역 속성이다.
    4. hasRestrictedGlobaltrue이면 SyntaxError 예외를 던진다.
  4. varNames의 각 요소 name에 대해
    1. HasLexicalDeclaration(env, name)이 true이면 SyntaxError 예외를 던진다.
  5. varDeclarationsscript의 VarScopedDeclarations로 둔다.
  6. functionsToInitialize를 새로운 빈 리스트로 둔다.
  7. declaredFunctionNames를 새로운 빈 리스트로 둔다.
  8. varDeclarations의 각 요소 d에 대해 역순으로
    1. dVariableDeclaration, ForBinding, 또는 BindingIdentifier가 아니면
      1. 단언: dFunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, 또는 AsyncGeneratorDeclaration 중 하나이다.
      2. 참고: 같은 이름에 대해 여러 함수 선언이 있으면 마지막 선언이 사용된다.
      3. fnd의 BoundNames의 유일한 요소로 둔다.
      4. declaredFunctionNamesfn을 포함하지 않으면
        1. fnDefinable을 ? CanDeclareGlobalFunction(env, fn)로 둔다.
        2. fnDefinablefalse이면 TypeError 예외를 던진다.
        3. fndeclaredFunctionNames에 추가한다.
        4. dfunctionsToInitialize의 첫 번째 요소로 삽입한다.
  9. declaredVarNames를 새로운 빈 리스트로 둔다.
  10. varDeclarations의 각 요소 d에 대해
    1. dVariableDeclaration, ForBinding, 또는 BindingIdentifier이면
      1. d의 BoundNames의 각 String vn에 대해
        1. declaredFunctionNamesvn을 포함하지 않으면
          1. vnDefinable을 ? CanDeclareGlobalVar(env, vn)로 둔다.
          2. vnDefinablefalse이면 TypeError 예외를 던진다.
          3. declaredVarNamesvn을 포함하지 않으면
            1. vndeclaredVarNames에 추가한다.
  11. 참고: 전역 객체일반 객체인 경우 이 알고리즘 단계 이후에는 비정상적인 종료가 발생하지 않는다. 그러나 전역 객체가 Proxy exotic 객체인 경우 다음 단계 중 일부에서 비정상적인 종료를 유발하는 동작을 보일 수 있다.
  12. Normative Optional
    호스트가 웹 브라우저이거나 그렇지 않으면 블록 수준 함수 선언 웹 레거시 호환 의미를 지원하면
    1. strictscript의 ScriptIsStrict로 둔다.
    2. strictfalse이면
      1. declaredFunctionOrVarNamesdeclaredFunctionNamesdeclaredVarNames의 리스트 연결로 둔다.
      2. scriptx를 포함하는 것이 trueBlock, CaseClause, 또는 DefaultClause xStatementList에 직접 포함된 각 FunctionDeclaration f에 대해
        1. FfBindingIdentifier의 StringValue로 둔다.
        2. FunctionDeclaration fFBindingIdentifier로 가진 VariableStatement로 대체하는 것이 script에 대해 조기 오류를 생성하지 않으면
          1. HasLexicalDeclaration(env, F)가 false이면
            1. fnDefinable을 ? CanDeclareGlobalVar(env, F)로 둔다.
            2. fnDefinabletrue이면
              1. 참고: F에 대한 var 바인딩은 VarDeclaredName도 아니고 다른 FunctionDeclaration의 이름도 아닌 경우에만 여기서 인스턴스화된다.
              2. declaredFunctionOrVarNamesF를 포함하지 않으면
                1. CreateGlobalVarBinding(env, F, false)를 수행한다.
                2. FdeclaredFunctionOrVarNames에 추가한다.
              3. FunctionDeclaration f가 평가될 때, 15.2.6에서 제공하는 FunctionDeclaration Evaluation 알고리즘 대신 다음 단계를 수행한다:
                1. gEnv를 실행 중인 실행 컨텍스트의 VariableEnvironment로 둔다.
                2. bEnv를 실행 중인 실행 컨텍스트의 LexicalEnvironment로 둔다.
                3. fObj를 ! bEnv.GetBindingValue(F, false)로 둔다.
                4. gEnv.SetMutableBinding(F, fObj, false)를 수행한다.
                5. unused를 반환한다.
  13. lexDeclarationsscript의 LexicallyScopedDeclarations로 둔다.
  14. privateEnvnull로 둔다.
  15. lexDeclarations의 각 요소 d에 대해
    1. 참고: 어휘적으로 선언된 이름은 여기서만 인스턴스화되고 초기화되지 않는다.
    2. d의 BoundNames의 각 요소 dn에 대해
      1. d의 IsConstantDeclaration이 true이면
        1. env.CreateImmutableBinding(dn, true)를 수행한다.
      2. 그렇지 않으면
        1. env.CreateMutableBinding(dn, false)를 수행한다.
  16. functionsToInitialize의 각 Parse Node f에 대해
    1. fnf의 BoundNames의 유일한 요소로 둔다.
    2. fo를 인수 envprivateEnv를 사용한 f의 InstantiateFunctionObject로 둔다.
    3. CreateGlobalFunctionBinding(env, fn, fo, false)를 수행한다.
  17. declaredVarNames의 각 String vn에 대해
    1. CreateGlobalVarBinding(env, vn, false)를 수행한다.
  18. unused를 반환한다.
Note 2

16.1.1에 명시된 조기 오류는 function/var 선언과 let/const/class 선언 간의 이름 충돌뿐만 아니라 단일 Script 내에 포함된 선언에 대한 let/const/class 바인딩의 재선언을 방지한다. 그러나 둘 이상의 Script에 걸친 이러한 충돌과 재선언은 GlobalDeclarationInstantiation 중에 런타임 오류로 감지된다. 이러한 오류가 감지되면 스크립트에 대해 바인딩이 인스턴스화되지 않는다. 그러나 전역 객체가 Proxy exotic 객체를 사용하여 정의된 경우 충돌하는 선언에 대한 런타임 테스트가 신뢰할 수 없어 abrupt completion과 일부 전역 선언이 인스턴스화되지 않을 수 있다. 이런 경우 Script의 코드는 평가되지 않는다.

명시적인 var 또는 function 선언과 달리, 전역 객체에서 직접 생성된 속성은 let/const/class 선언에 의해 가려질 수 있는 전역 바인딩을 만든다.

16.2 모듈

구문

Module : ModuleBodyopt ModuleBody : ModuleItemList ModuleItemList : ModuleItem ModuleItemList ModuleItem ModuleItem : ImportDeclaration ExportDeclaration StatementListItem[~Yield, +Await, ~Return] ModuleExportName : IdentifierName StringLiteral

16.2.1 모듈 의미론

16.2.1.1 정적 의미론: 조기 오류

ModuleBody : ModuleItemList
  • ModuleItemList의 LexicallyDeclaredNames가 중복 항목을 포함하면 구문 오류이다.
  • ModuleItemList의 LexicallyDeclaredNames의 어떤 요소가 ModuleItemList의 VarDeclaredNames에도 나타나면 구문 오류이다.
  • ModuleItemList의 ExportedNames가 중복 항목을 포함하면 구문 오류이다.
  • ModuleItemList의 ExportedBindings의 어떤 요소가 ModuleItemList의 VarDeclaredNames 또는 LexicallyDeclaredNames에 나타나지 않으면 구문 오류이다.
  • ModuleItemListsuper를 포함하면 구문 오류이다.
  • ModuleItemListNewTarget을 포함하면 구문 오류이다.
  • 인수 « »를 사용한 ModuleItemList의 ContainsDuplicateLabels가 true이면 구문 오류이다.
  • 인수 « »를 사용한 ModuleItemList의 ContainsUndefinedBreakTarget이 true이면 구문 오류이다.
  • 인수 « »와 « »를 사용한 ModuleItemList의 ContainsUndefinedContinueTarget이 true이면 구문 오류이다.
  • 인수 « »를 사용한 ModuleItemList의 AllPrivateIdentifiersValid가 false이면 구문 오류이다.
Note

중복된 ExportedNames 규칙은 ModuleBody 내에서 여러 export default ExportDeclaration 항목이 구문 오류임을 의미한다. 충돌하거나 중복된 선언과 관련된 추가 오류 조건은 Module 평가 전에 모듈 링킹 중에 확인된다. 이러한 오류가 감지되면 Module은 평가되지 않는다.

ModuleExportName : StringLiteral

16.2.1.2 정적 의미론: ImportedLocalNames ( importEntries: ImportEntry Records의 리스트, ): 문자열의 리스트

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

  1. localNames를 새로운 빈 리스트로 둔다.
  2. importEntries의 각 ImportEntry Record i에 대해
    1. i.[[LocalName]]localNames에 추가한다.
  3. localNames를 반환한다.

16.2.1.3 ModuleRequest 레코드

ModuleRequest 레코드는 주어진 가져오기 속성을 가진 모듈을 가져오는 요청을 나타낸다. 다음 필드들로 구성된다:

Table 38: ModuleRequest 레코드 필드
필드 이름 값 타입 의미
[[Specifier]] 문자열 모듈 지정자
[[Attributes]] ImportAttribute Records의 리스트 가져오기 속성

LoadedModuleRequest 레코드는 모듈을 가져오는 요청과 결과 Module Record를 함께 나타낸다. 표 Table 38에 정의된 동일한 필드들과 [[Module]] 필드의 추가로 구성된다:

Table 39: LoadedModuleRequest 레코드 필드
필드 이름 값 타입 의미
[[Specifier]] 문자열 모듈 지정자
[[Attributes]] ImportAttribute Records의 리스트 가져오기 속성
[[Module]] Module Record 이 모듈 요청에 해당하는 로드된 모듈

ImportAttribute 레코드는 다음 필드들로 구성된다:

Table 40: ImportAttribute 레코드 필드
필드 이름 값 타입 의미
[[Key]] 문자열 속성 키
[[Value]] 문자열 속성 값

16.2.1.3.1 ModuleRequestsEqual ( left, right )

The abstract operation ModuleRequestsEqual takes arguments left (ModuleRequest Record 또는 LoadedModuleRequest Record) and right (ModuleRequest Record 또는 LoadedModuleRequest Record) and returns Boolean. It performs the following steps when called:

  1. left.[[Specifier]]right.[[Specifier]]와 같지 않으면 false를 반환한다.
  2. leftAttrsleft.[[Attributes]]로 둔다.
  3. rightAttrsright.[[Attributes]]로 둔다.
  4. leftAttrsCountleftAttrs의 요소 개수로 둔다.
  5. rightAttrsCountrightAttrs의 요소 개수로 둔다.
  6. leftAttrsCountrightAttrsCount이면 false를 반환한다.
  7. leftAttrs의 각 ImportAttribute Record l에 대해
    1. rightAttrsl.[[Key]]r.[[Key]]이고 l.[[Value]]r.[[Value]]인 ImportAttribute Record r을 포함하지 않으면 false를 반환한다.
  8. true를 반환한다.

16.2.1.4 정적 의미론: ModuleRequests : ModuleRequest Records의 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

Module : [empty]
  1. 새로운 빈 리스트를 반환한다.
ModuleItemList : ModuleItem
  1. ModuleItem의 ModuleRequests를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. requestsModuleItemList의 ModuleRequests로 둔다.
  2. additionalRequestsModuleItem의 ModuleRequests로 둔다.
  3. additionalRequests의 각 ModuleRequest Record mr에 대해
    1. requestsModuleRequestsEqual(mr, mr2)이 true인 ModuleRequest Record mr2를 포함하지 않으면
      1. mrrequests에 추가한다.
  4. requests를 반환한다.
ModuleItem : StatementListItem
  1. 새로운 빈 리스트를 반환한다.
ImportDeclaration : import ImportClause FromClause ;
  1. specifierFromClause의 SV로 둔다.
  2. ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » }가 유일한 요소인 리스트를 반환한다.
ImportDeclaration : import ImportClause FromClause WithClause ;
  1. specifierFromClause의 SV로 둔다.
  2. attributesWithClause의 WithClauseToAttributes로 둔다.
  3. ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes }가 유일한 요소인 리스트를 반환한다.
ImportDeclaration : import ModuleSpecifier ;
  1. specifierModuleSpecifier의 SV로 둔다.
  2. ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » }가 유일한 요소인 리스트를 반환한다.
ImportDeclaration : import ModuleSpecifier WithClause ;
  1. specifierModuleSpecifier의 SV로 둔다.
  2. attributesWithClause의 WithClauseToAttributes로 둔다.
  3. ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes }가 유일한 요소인 리스트를 반환한다.
ExportDeclaration : export ExportFromClause FromClause ;
  1. specifierFromClause의 SV로 둔다.
  2. ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » }가 유일한 요소인 리스트를 반환한다.
ExportDeclaration : export ExportFromClause FromClause WithClause ;
  1. specifierFromClause의 SV로 둔다.
  2. attributesWithClause의 WithClauseToAttributes로 둔다.
  3. ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes }가 유일한 요소인 리스트를 반환한다.
ExportDeclaration : export NamedExports ; export VariableStatement export Declaration export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. 새로운 빈 리스트를 반환한다.

16.2.1.5 추상 모듈 레코드

모듈 레코드는 단일 모듈의 가져오기와 내보내기에 대한 구조적 정보를 캡슐화한다. 이 정보는 연결된 모듈 집합의 가져오기와 내보내기를 링크하는 데 사용된다. 모듈 레코드는 모듈을 평가할 때만 사용되는 네 개의 필드를 포함한다.

명세 목적상 Module Record 값은 Record 명세 타입의 값이며, Module Record가 추상 클래스이고 추상 및 구체적 하위 클래스를 모두 가진 간단한 객체 지향 계층 구조에 존재하는 것으로 생각할 수 있다. 이 명세는 Cyclic Module Record라는 추상 하위 클래스와 그 구체적 하위 클래스인 Source Text Module Record를 정의한다. 다른 명세와 구현은 그들이 정의한 대안적인 모듈 정의 기능에 해당하는 추가적인 Module Record 하위 클래스를 정의할 수 있다.

Module RecordTable 41에 나열된 필드들을 정의한다. 모든 Module Definition 하위 클래스는 적어도 이러한 필드들을 포함한다. Module Record는 또한 Table 42의 추상 메서드 리스트를 정의한다. 모든 Module definition 하위 클래스는 이러한 추상 메서드들의 구체적인 구현을 제공해야 한다.

Table 41: 모듈 레코드 필드
필드 이름 값 타입 의미
[[Realm]] Realm Record 이 모듈이 생성된 Realm.
[[Environment]] Module Environment Record 또는 empty 이 모듈의 최상위 바인딩을 포함하는 Environment Record. 이 필드는 모듈이 링크될 때 설정된다.
[[Namespace]] Object 또는 empty 이 모듈에 대해 생성된 Module Namespace Object (28.3).
[[HostDefined]] anything (기본값은 undefined) 모듈과 추가 정보를 연결해야 하는 호스트 환경에서 사용하기 위해 예약된 필드.
Table 42: 모듈 레코드의 추상 메서드
메서드 목적
LoadRequestedModules([hostDefined])

모든 의존성을 재귀적으로 로드하여 모듈을 링킹을 위해 준비하고 프로미스를 반환한다.

GetExportedNames([exportStarSet])

이 모듈에서 직접 또는 간접적으로 내보내지는 모든 이름의 리스트를 반환한다.

이 메서드를 호출하기 전에 LoadRequestedModules가 성공적으로 완료되어야 한다.

ResolveExport(exportName [, resolveSet])

이 모듈에서 내보낸 이름의 바인딩을 반환한다. 바인딩은 { [[Module]]: Module Record, [[BindingName]]: String | namespace } 형태의 ResolvedBinding Record로 표현된다. 내보내기가 어떤 모듈에서도 직접 바인딩이 없는 Module Namespace Object인 경우 [[BindingName]]namespace로 설정된다. 이름을 해결할 수 없으면 null을, 여러 바인딩이 발견되면 ambiguous를 반환한다.

특정 exportName, resolveSet 쌍을 인수로 이 연산을 호출할 때마다 동일한 결과를 반환해야 한다.

이 메서드를 호출하기 전에 LoadRequestedModules가 성공적으로 완료되어야 한다.

Link()

모든 모듈 의존성을 전이적으로 해결하고 Module Environment Record를 생성하여 모듈을 평가를 위해 준비한다.

이 메서드를 호출하기 전에 LoadRequestedModules가 성공적으로 완료되어야 한다.

Evaluate()

이 모듈과 그 의존성의 평가에 대한 프로미스를 반환하며, 성공적인 평가 시 또는 이미 성공적으로 평가된 경우 해결되고, 평가 오류 시 또는 이미 성공적이지 않게 평가된 경우 거부된다. 프로미스가 거부되면 호스트는 프로미스 거부를 처리하고 평가 오류를 다시 던질 것으로 예상된다.

이 메서드를 호출하기 전에 Link가 성공적으로 완료되어야 한다.

16.2.1.5.1 EvaluateModuleSync ( module )

The abstract operation EvaluateModuleSync takes argument module (Module Record) and returns unused를 포함하는 정상 완료 또는 throw completion. It performs the following steps when called:

  1. 단언: moduleCyclic Module Record가 아니다.
  2. promisemodule.Evaluate()로 둔다.
  3. 단언: promise.[[PromiseState]]fulfilled 또는 rejected 중 하나이다.
  4. promise.[[PromiseState]]rejected이면
    1. promise.[[PromiseIsHandled]]false이면 HostPromiseRejectionTracker(promise, "handle")를 수행한다.
    2. promise.[[PromiseIsHandled]]true로 설정한다.
    3. ThrowCompletion(promise.[[PromiseResult]])를 반환한다.
  5. unused를 반환한다.

16.2.1.6 순환 모듈 레코드

Cyclic Module RecordCyclic Module Record 타입의 하위 클래스인 다른 모듈들과 의존성 순환(dependency cycle)에 참여할 수 있는 모듈에 대한 정보를 표현하는 데 사용된다. Cyclic Module Record 타입의 하위 클래스가 아닌 Module RecordSource Text Module Record 와의 의존성 순환에 참여해서는 안 된다.

Table 41에 정의된 필드들에 더해, Cyclic Module RecordTable 43에 나열된 추가 필드를 가진다.

Table 43: Cyclic Module Record 의 추가 필드
필드 이름 값 타입 의미
[[Status]] new, unlinked, linking, linked, evaluating, evaluating-async, 또는 evaluated 초기 값은 new. 모듈 생명주기 진행에 따라 순서대로 unlinked, linking, linked, evaluating, 필요 시 evaluating-async, evaluated 로 전이한다. evaluating-async 는 이 모듈이 비동기 의존성 완료 후 실행 대기열에 들어 있거나, [[HasTLA]] 필드가 true 이어서 실행되었고 최상위 완료를 대기 중임을 나타낸다.
[[EvaluationError]] throw completion 또는 empty 평가 중 발생한 예외를 나타내는 throw completion. 예외가 없었거나 [[Status]]evaluated 가 아니면 undefined.
[[DFSAncestorIndex]] 정수 또는 empty Link 및 Evaluate 동안에만 사용하는 보조 필드. [[Status]]linking 또는 evaluating 이면, 모듈 자신의 DFS(깊이 우선 탐색) 인덱스이거나 동일 SCC(강한 연결 요소) 내 “더 이른” 모듈의 인덱스이다.
[[RequestedModules]] ModuleRequest Record 리스트 이 모듈의 import 들에 연관된 ModuleRequest Record 리스트. 소스 텍스트상의 등장 순서를 따른다.
[[LoadedModules]] LoadedModuleRequest Record 리스트 Record가 표현하는 모듈이 사용한 지정자 문자열을 (상대 import 속성 집합과 함께) 해석된 Module Record 로 매핑하는 맵. ModuleRequestsEqual(r1, r2)가 true 인 서로 다른 Record r1, r2 를 두 개 포함하지 않는다.
[[CycleRoot]] Cyclic Module Record 또는 empty 순환의 최초 방문 모듈, 즉 SCC 의 루트 DFS 선조. 순환에 속하지 않는 모듈이면 자기 자신. Evaluate 완료 후 모듈의 [[DFSAncestorIndex]] 는 그 [[CycleRoot]] 의 DFS 인덱스가 된다.
[[HasTLA]] Boolean 이 모듈이 개별적으로 비동기인지 여부(예: top-level await 를 포함하는 Source Text Module Record). 비동기 의존성이 있다는 사실만으로 true 는 아니다. 파싱 후 이 필드는 변하지 않는다.
[[AsyncEvaluationOrder]] unset, 정수, 또는 done 초기 unset 이며 완전 동기 모듈은 계속 unset. 자체가 비동기이거나 비동기 의존성을 가지는 모듈은 16.2.1.6.1.3.4 에 의해 대기 모듈 실행이 큐잉되는 순서를 결정하는 정수로 설정된다. 대기 모듈이 실행되면 done 으로 설정.
[[TopLevelCapability]] PromiseCapability Record 또는 empty 이 모듈이 어떤 순환의 [[CycleRoot]] 이고 그 순환 내 어떤 모듈에 Evaluate() 가 호출되었다면, 그 전체 평가에 대한 PromiseCapability Record. Evaluate() 추상 메서드가 반환한 Promise 객체 해결에 사용된다. 해당 순환의 의존 모듈들은 최상위 Evaluate() 가 그들에 대해 개시되지 않았다면 empty.
[[AsyncParentModules]] Cyclic Module Record 리스트 이 모듈 또는 그 의존성이 [[HasTLA]] true 인 상태로 실행 진행 중이면, 최상위 실행 작업에 대해 이 모듈의 상위 importer 들을 추적한다. 이 부모 모듈들은 이 모듈이 성공적으로 실행 완료하기 전에는 실행을 시작하지 않는다.
[[PendingAsyncDependencies]] 정수 또는 empty 비동기 의존성이 하나라도 있으면 남은 비동기 의존 모듈 수를 추적한다. 이 값이 0 이고 실행 오류가 없을 때 모듈이 실행된다.

Table 42 에 정의된 메서드들에 더해 Cyclic Module RecordTable 44 에 나열된 추가 메서드를 가진다.

Table 44: Cyclic Module Record 의 추가 추상 메서드
메서드 목적
InitializeEnvironment() 모든 import 된 바인딩을 해석하고 모듈의 Environment Record 를 초기화하며 실행 컨텍스트를 생성한다.
ExecuteModule([promiseCapability]) 모듈의 실행 컨텍스트 내에서 코드 평가. 이 모듈이 [[HasTLA]]true 이면 PromiseCapability Record 가 인수로 전달되며 메서드는 해당 capability 를 resolve 또는 reject 해야 한다. 이 경우 예외를 throw 하지 말고 필요 시 PromiseCapability Record 를 reject 해야 한다.

GraphLoadingState Record 는 모듈 그래프 로딩 과정에 대한 정보를 담는 Record 이다. HostLoadImportedModule 호출 이후 로딩을 계속하기 위해 사용된다. 각 GraphLoadingState RecordTable 45 에 정의된 필드를 가진다:

Table 45: GraphLoadingState Record 필드
필드 이름 값 타입 의미
[[PromiseCapability]] PromiseCapability Record 로딩 프로세스 완료 시 resolve 해야 하는 Promise.
[[IsLoading]] Boolean 로딩이 아직 성공/오류 어떤 형태로도 완료되지 않았으면 true.
[[PendingModulesCount]] 음이 아닌 정수 대기 중인 HostLoadImportedModule 호출 수를 추적.
[[Visited]] Cyclic Module Record 리스트 현재 로딩 과정에서 이미 로드된 Cyclic Module Record 리스트(순환 의존 무한 루프 방지).
[[HostDefined]] anything (기본값 empty) LoadRequestedModules 호출자에서 HostLoadImportedModule 로 전달할 호스트 정의 데이터.

16.2.1.6.1 Module Record 추상 메서드 구현

다음은 Table 42 에 정의된 Module Record 추상 메서드를 구현하는 Cyclic Module Record 의 구체 메서드이다.

16.2.1.6.1.1 LoadRequestedModules ( [ hostDefined ] )

The LoadRequestedModules concrete method of Cyclic Module Record module takes optional argument hostDefined (anything) and returns Promise. module 의 의존성 그래프 내 모든 Module Record[[LoadedModules]] 를 채운다(주요 작업은 보조 함수 InnerModuleLoading 이 수행). 선택적 hostDefinedHostLoadImportedModule 훅에 전달된다. It performs the following steps when called:

  1. hostDefined 가 없으면 hostDefinedempty 로 둔다.
  2. pc 를 ! NewPromiseCapability(%Promise%) 로 둔다.
  3. stateGraphLoadingState Record { [[IsLoading]]: true, [[PendingModulesCount]]: 1, [[Visited]]: « », [[PromiseCapability]]: pc, [[HostDefined]]: hostDefined } 로 둔다.
  4. InnerModuleLoading(state, module) 를 수행한다.
  5. pc.[[Promise]] 를 반환한다.
Note
hostDefined 매개변수는 import 된 모듈을 가져오는 데 필요한 추가 정보를 전달하는 데 사용할 수 있다. 예를 들어 HTML 은 <link rel="preload" as="..."> 태그에 대한 올바른 fetch destination 설정에 사용한다. import() 표현식은 hostDefined 를 설정하지 않는다.

16.2.1.6.1.1.1 InnerModuleLoading ( state, module )

The abstract operation InnerModuleLoading takes arguments state (GraphLoadingState Record) and module (Module Record) and returns unused. LoadRequestedModules 가 module 의 의존성 그래프에 대해 실제 로딩을 재귀적으로 수행할 때 사용된다. It performs the following steps when called:

  1. 단언: state.[[IsLoading]]true.
  2. moduleCyclic Module Record 이고, module.[[Status]]new, 그리고 state.[[Visited]]module 을 포함하지 않으면
    1. modulestate.[[Visited]] 에 추가한다.
    2. requestedModulesCountmodule.[[RequestedModules]] 요소 수로 둔다.
    3. state.[[PendingModulesCount]]state.[[PendingModulesCount]] + requestedModulesCount 로 설정.
    4. module.[[RequestedModules]] 의 각 ModuleRequest Record request 에 대해
      1. AllImportAttributesSupported(request.[[Attributes]]) 가 false 이면
        1. errorThrowCompletion(새로 생성된 SyntaxError 객체) 로 둔다.
        2. ContinueModuleLoading(state, error) 수행.
      2. Else if module.[[LoadedModules]]ModuleRequestsEqual(record, request) 가 true 인 LoadedModuleRequest Record record 를 포함하면
        1. InnerModuleLoading(state, record.[[Module]]) 수행.
      3. Else,
        1. HostLoadImportedModule(module, request, state.[[HostDefined]], state) 수행.
        2. 참고: HostLoadImportedModuleFinishLoadingImportedModule 를 호출하고 이는 ContinueModuleLoading 을 통해 그래프 로딩 과정에 재진입한다.
      4. state.[[IsLoading]]false 이면 unused 반환.
  3. 단언: state.[[PendingModulesCount]] ≥ 1.
  4. state.[[PendingModulesCount]]state.[[PendingModulesCount]] - 1 로 설정.
  5. state.[[PendingModulesCount]] = 0 이면
    1. state.[[IsLoading]]false 로 둔다.
    2. state.[[Visited]] 의 각 Cyclic Module Record loaded 에 대해
      1. loaded.[[Status]]new 이면 unlinked 로 설정.
    3. Call(state.[[PromiseCapability]].[[Resolve]], undefined, « undefined ») 수행.
  6. unused 반환.

16.2.1.6.1.1.2 ContinueModuleLoading ( state, moduleCompletion )

The abstract operation ContinueModuleLoading takes arguments state (GraphLoadingState Record) and moduleCompletion (Module Record 를 담은 정상 completion 또는 throw completion) and returns unused. HostLoadImportedModule 호출 후 로딩 과정에 재진입할 때 사용된다. It performs the following steps when called:

  1. state.[[IsLoading]]false 이면 unused 반환.
  2. moduleCompletion 이 정상 completion 이면
    1. InnerModuleLoading(state, moduleCompletion.[[Value]]) 수행.
  3. Else,
    1. state.[[IsLoading]]false 로 둔다.
    2. Call(state.[[PromiseCapability]].[[Reject]], undefined, « moduleCompletion.[[Value]] ») 수행.
  4. unused 반환.

16.2.1.6.1.2 Link ( )

The Link concrete method of Cyclic Module Record module takes no arguments and returns unused 를 담은 정상 completion 또는 throw completion. 성공 시 이 모듈의 [[Status]]unlinked 에서 linked 로 전이. 실패 시 예외를 던지고 [[Status]]unlinked 유지. (주요 작업은 보조 함수 InnerModuleLinking 수행) It performs the following steps when called:

  1. 단언: module.[[Status]]unlinked, linked, evaluating-async, evaluated 중 하나.
  2. stack 을 새 빈 리스트로 둔다.
  3. resultCompletion(InnerModuleLinking(module, stack, 0)) 로 둔다.
  4. resultabrupt completion 이면
    1. stack 의 각 Cyclic Module Record m 에 대해
      1. 단언: m.[[Status]]linking.
      2. m.[[Status]]unlinked 로 설정.
    2. 단언: module.[[Status]]unlinked.
    3. result 반환.
  5. 단언: module.[[Status]]linked, evaluating-async, 또는 evaluated 중 하나.
  6. 단언: stack 은 비어 있음.
  7. unused 반환.

16.2.1.6.1.2.1 InnerModuleLinking ( module, stack, index )

The abstract operation InnerModuleLinking takes arguments module (Module Record), stack (Cyclic Module Record 리스트), and index (음이 아닌 정수) and returns 음이 아닌 정수를 담은 정상 completion 또는 throw completion. Link 가 module 및 의존성 그래프의 다른 모듈들에 대해 실제 링크 과정을 수행. stackindex, 그리고 모듈의 [[DFSAncestorIndex]] 는 DFS 탐색 추적에 사용. 특히 [[DFSAncestorIndex]] 로 SCC 를 발견하여 SCC 내 모든 모듈이 함께 linked 로 전이되도록 한다. It performs the following steps when called:

  1. moduleCyclic Module Record 가 아니면
    1. module.Link() 수행.
    2. index 반환.
  2. module.[[Status]]linking, linked, evaluating-async, evaluated 중 하나이면
    1. index 반환.
  3. 단언: module.[[Status]]unlinked.
  4. module.[[Status]]linking 으로 둔다.
  5. moduleIndexindex 로 둔다.
  6. module.[[DFSAncestorIndex]]index 로 둔다.
  7. indexindex + 1 로 설정.
  8. modulestack 에 추가.
  9. module.[[RequestedModules]] 의 각 ModuleRequest Record request 에 대해
    1. requiredModuleGetImportedModule(module, request) 로 둔다.
    2. index 를 ? InnerModuleLinking(requiredModule, stack, index) 로 설정.
    3. requiredModuleCyclic Module Record 이면
      1. 단언: requiredModule.[[Status]]linking, linked, evaluating-async, evaluated 중 하나.
      2. 단언: requiredModule.[[Status]]linking 인 것은 stackrequiredModule 을 포함함과 동치.
      3. requiredModule.[[Status]]linking 이면
        1. module.[[DFSAncestorIndex]]min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]) 로 설정.
  10. module.InitializeEnvironment() 수행.
  11. 단언: modulestack 에 정확히 한 번 등장.
  12. 단언: module.[[DFSAncestorIndex]]moduleIndex.
  13. module.[[DFSAncestorIndex]] = moduleIndex 이면
    1. donefalse 로 둔다.
    2. 반복: donefalse 인 동안
      1. requiredModulestack 마지막 요소로 둔다.
      2. 마지막 요소 제거.
      3. 단언: requiredModuleCyclic Module Record.
      4. requiredModule.[[Status]]linked 로 설정.
      5. requiredModulemodule 이 동일 Module Record 이면 done = true.
  14. index 반환.

16.2.1.6.1.3 Evaluate ( )

The Evaluate concrete method of Cyclic Module Record module takes no arguments and returns Promise. Evaluate 는 이 모듈의 [[Status]]linked 에서 evaluating-async 또는 evaluated 로 전이. 동일 SCC 내에서 처음 호출될 때 Promise 를 생성해 모듈 평가 완료 시 resolve. 이 Promise 는 구성 요소 [[CycleRoot]][[TopLevelCapability]] 에 저장. 이후 SCC 내 어떤 모듈에 대한 Evaluate 호출도 동일 Promise 반환. (주요 작업은 보조 함수 InnerModuleEvaluation 수행) It performs the following steps when called:

  1. 단언: 이 Evaluate 호출은 동일 agent 내 다른 Evaluate 호출과 동시에 일어나지 않음.
  2. 단언: module.[[Status]]linked, evaluating-async, evaluated 중 하나.
  3. module.[[Status]]evaluating-async 또는 evaluated 이면 module = module.[[CycleRoot]].
  4. module.[[TopLevelCapability]]empty 가 아니면
    1. module.[[TopLevelCapability]].[[Promise]] 반환.
  5. stack 을 새 빈 리스트로 둔다.
  6. capability 를 ! NewPromiseCapability(%Promise%) 로 둔다.
  7. module.[[TopLevelCapability]]capability 로 둔다.
  8. resultCompletion(InnerModuleEvaluation(module, stack, 0)) 로 둔다.
  9. resultabrupt completion 이면
    1. stack 의 각 Cyclic Module Record m 에 대해
      1. 단언: m.[[Status]]evaluating.
      2. 단언: m.[[AsyncEvaluationOrder]]unset.
      3. m.[[Status]]evaluated 로.
      4. m.[[EvaluationError]]result 로.
    2. 단언: module.[[Status]]evaluated.
    3. 단언: module.[[EvaluationError]]result 는 동일 Completion Record.
    4. Call(capability.[[Reject]], undefined, « result.[[Value]] ») 수행.
  10. Else,
    1. 단언: module.[[Status]]evaluating-async 또는 evaluated.
    2. 단언: module.[[EvaluationError]]empty.
    3. module.[[Status]]evaluated 이면
      1. 참고: module 평가가 동기적으로 완료되었음을 의미.
      2. 단언: module.[[AsyncEvaluationOrder]]unset.
      3. Call(capability.[[Resolve]], undefined, « undefined ») 수행.
    4. 단언: stack 은 비어 있음.
  11. capability.[[Promise]] 반환.

16.2.1.6.1.3.1 InnerModuleEvaluation ( module, stack, index )

The abstract operation InnerModuleEvaluation takes arguments module (Module Record), stack (Cyclic Module Record 리스트), and index (음이 아닌 정수) and returns 음이 아닌 정수를 담은 정상 completion 또는 throw completion. Evaluate 가 module 및 의존성 그래프의 다른 모듈에 대해 실제 평가 과정을 수행. stack, index, 그리고 module[[DFSAncestorIndex]] 사용 방식은 InnerModuleLinking 과 동일. It performs the following steps when called:

  1. moduleCyclic Module Record 가 아니면
    1. EvaluateModuleSync(module) 수행.
    2. index 반환.
  2. module.[[Status]]evaluating-async 또는 evaluated 이면
    1. module.[[EvaluationError]]empty 이면 index 반환.
    2. 아니면 ? module.[[EvaluationError]] 반환.
  3. module.[[Status]]evaluating 이면 index 반환.
  4. 단언: module.[[Status]]linked.
  5. module.[[Status]]evaluating 으로.
  6. moduleIndex = index.
  7. module.[[DFSAncestorIndex]] = index.
  8. module.[[PendingAsyncDependencies]] = 0.
  9. index = index + 1.
  10. modulestack 에 추가.
  11. module.[[RequestedModules]] 의 각 ModuleRequest Record request 에 대해
    1. requiredModule = GetImportedModule(module, request).
    2. index = ? InnerModuleEvaluation(requiredModule, stack, index).
    3. requiredModuleCyclic Module Record 이면
      1. 단언: requiredModule.[[Status]]evaluating, evaluating-async, evaluated 중 하나.
      2. 단언: requiredModule.[[Status]]evaluating 인 것은 stackrequiredModule 포함과 동치.
      3. requiredModule.[[Status]]evaluating 이면
        1. module.[[DFSAncestorIndex]] = min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]).
      4. Else,
        1. requiredModule = requiredModule.[[CycleRoot]].
        2. 단언: requiredModule.[[Status]]evaluating-async 또는 evaluated.
        3. requiredModule.[[EvaluationError]]empty 가 아니면 ? requiredModule.[[EvaluationError]] 반환.
      5. requiredModule.[[AsyncEvaluationOrder]] 가 정수이면
        1. module.[[PendingAsyncDependencies]] += 1.
        2. modulerequiredModule.[[AsyncParentModules]] 에 추가.
  12. module.[[PendingAsyncDependencies]] > 0 또는 module.[[HasTLA]]true 이면
    1. 단언: module.[[AsyncEvaluationOrder]]unset.
    2. module.[[AsyncEvaluationOrder]] = IncrementModuleAsyncEvaluationCount().
    3. module.[[PendingAsyncDependencies]] = 0 이면 ExecuteAsyncModule(module) 수행.
  13. Else,
    1. module.ExecuteModule() 수행.
  14. 단언: modulestack 에 정확히 한 번 등장.
  15. 단언: module.[[DFSAncestorIndex]]moduleIndex.
  16. module.[[DFSAncestorIndex]] = moduleIndex 이면
    1. done = false.
    2. 반복 (donefalse 인 동안)
      1. requiredModule = stack 마지막 요소.
      2. 마지막 요소 제거.
      3. 단언: requiredModuleCyclic Module Record.
      4. 단언: requiredModule.[[AsyncEvaluationOrder]] 는 정수 또는 unset.
      5. requiredModule.[[AsyncEvaluationOrder]]unset 이면 requiredModule.[[Status]] = evaluated.
      6. 아니면 requiredModule.[[Status]] = evaluating-async.
      7. requiredModulemodule 이 같으면 done = true.
      8. requiredModule.[[CycleRoot]] = module.
  17. index 반환.
Note 1

모듈은 InnerModuleEvaluation 이 순회 중이면 evaluating 상태. [[HasTLA]]true 이거나 비동기 의존성이 있으면 실행 중 evaluating-async, 완료 시 evaluated.

Note 2

비동기 순환의 모듈에 의존하는 모듈은 순환이 evaluating 이 아닐 때 [[CycleRoot]] 를 통해 루트 실행에 의존하도록 하여 순환 상태를 단일 SCC 로 취급 가능하게 한다.

16.2.1.6.1.3.2 ExecuteAsyncModule ( module )

The abstract operation ExecuteAsyncModule takes argument module (Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. 단언: module.[[Status]]evaluating 또는 evaluating-async.
  2. 단언: module.[[HasTLA]]true.
  3. capability = ! NewPromiseCapability(%Promise%).
  4. fulfilledClosuremodule 을 캡처하고 호출 시:
    1. AsyncModuleExecutionFulfilled(module) 수행.
    2. NormalCompletion(undefined) 반환.
  5. onFulfilled = CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
  6. rejectedClosure 를 (error) 매개변수, module 캡처하고 호출 시:
    1. AsyncModuleExecutionRejected(module, error) 수행.
    2. NormalCompletion(undefined) 반환.
  7. onRejected = CreateBuiltinFunction(rejectedClosure, 0, "", « »).
  8. PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected) 수행.
  9. module.ExecuteModule(capability) 수행.
  10. unused 반환.

16.2.1.6.1.3.3 GatherAvailableAncestors ( module, execList )

The abstract operation GatherAvailableAncestors takes arguments module (Cyclic Module Record) and execList (Cyclic Module Record 리스트) and returns unused. It performs the following steps when called:

  1. module.[[AsyncParentModules]] 의 각 Cyclic Module Record m 에 대해
    1. execListm 을 포함하지 않고 m.[[CycleRoot]].[[EvaluationError]]empty 이면
      1. 단언: m.[[Status]]evaluating-async.
      2. 단언: m.[[EvaluationError]]empty.
      3. 단언: m.[[AsyncEvaluationOrder]] 는 정수.
      4. 단언: m.[[PendingAsyncDependencies]] > 0.
      5. m.[[PendingAsyncDependencies]] -= 1.
      6. m.[[PendingAsyncDependencies]] = 0 이면
        1. mexecList 에 추가.
        2. m.[[HasTLA]]false 이면 GatherAvailableAncestors(m, execList) 수행.
  2. unused 반환.
Note

루트 module 의 비동기 실행이 fulfill 될 때, 이 함수는 동시에 동기 실행 가능한 모듈 목록을 결정하여 execList 에 채운다.

16.2.1.6.1.3.4 AsyncModuleExecutionFulfilled ( module )

The abstract operation AsyncModuleExecutionFulfilled takes argument module (Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. module.[[Status]]evaluated 이면
    1. 단언: module.[[EvaluationError]]empty 가 아님.
    2. unused 반환.
  2. 단언: module.[[Status]]evaluating-async.
  3. 단언: module.[[AsyncEvaluationOrder]] 는 정수.
  4. 단언: module.[[EvaluationError]]empty.
  5. module.[[AsyncEvaluationOrder]]done 으로.
  6. module.[[Status]]evaluated 로.
  7. module.[[TopLevelCapability]]empty 가 아니면
    1. 단언: module.[[CycleRoot]]module 은 동일.
    2. Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined ») 수행.
  8. execList 를 새 빈 리스트로 둔다.
  9. GatherAvailableAncestors(module, execList) 수행.
  10. 단언: execList 모든 요소는 [[AsyncEvaluationOrder]] 가 정수, [[PendingAsyncDependencies]] = 0, [[EvaluationError]] = empty.
  11. sortedExecList[[AsyncEvaluationOrder]] 오름차순으로 정렬한 리스트로 둔다.
  12. sortedExecList 의 각 Cyclic Module Record m 에 대해
    1. m.[[Status]]evaluated 이면
      1. 단언: m.[[EvaluationError]]empty 아님.
    2. Else if m.[[HasTLA]]true 이면
      1. ExecuteAsyncModule(m) 수행.
    3. Else
      1. result = m.ExecuteModule().
      2. resultabrupt completion 이면
        1. AsyncModuleExecutionRejected(m, result.[[Value]]) 수행.
      3. Else
        1. m.[[AsyncEvaluationOrder]] = done.
        2. m.[[Status]] = evaluated.
        3. m.[[TopLevelCapability]]empty 아니면
          1. 단언: m.[[CycleRoot]]m 동일.
          2. Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined ») 수행.
  13. unused 반환.

16.2.1.6.1.3.5 AsyncModuleExecutionRejected ( module, error )

The abstract operation AsyncModuleExecutionRejected takes arguments module (Cyclic Module Record) and error (ECMAScript 언어 값) and returns unused. It performs the following steps when called:

  1. module.[[Status]]evaluated 이면
    1. 단언: module.[[EvaluationError]]empty 가 아님.
    2. unused 반환.
  2. 단언: module.[[Status]]evaluating-async.
  3. 단언: module.[[AsyncEvaluationOrder]] 는 정수.
  4. 단언: module.[[EvaluationError]]empty.
  5. module.[[EvaluationError]] = ThrowCompletion(error).
  6. module.[[Status]] = evaluated.
  7. module.[[AsyncEvaluationOrder]] = done.
  8. 참고: module.[[EvaluationError]]empty 가 아닐 때 InnerModuleEvaluation 에서 [[AsyncEvaluationOrder]] 값은 사용되지 않는다.
  9. module.[[AsyncParentModules]] 의 각 Cyclic Module Record m 에 대해
    1. AsyncModuleExecutionRejected(m, error) 수행.
  10. module.[[TopLevelCapability]]empty 아니면
    1. 단언: module.[[CycleRoot]]module 동일.
    2. Call(module.[[TopLevelCapability]].[[Reject]], undefined, « error ») 수행.
  11. unused 반환.

16.2.1.6.2 순환 모듈 레코드 그래프 예시

비규범 섹션: 몇 가지 공통 모듈 그래프의 링크 및 평가 예시와 오류 발생 양상에 초점을 둔다.

먼저 다음 단순 모듈 그래프를 보자:

Figure 2: 단순 모듈 그래프
모듈 A 가 모듈 B 에 의존하고, 모듈 B 가 모듈 C 에 의존하는 그래프

우선 오류 조건이 없다고 가정. 호스트가 처음 A.LoadRequestedModules() 를 호출하면 (가정에 따라) 성공적으로 완료하면서 B, C 의 의존성도 재귀적으로 로드(각각 C 와 없음)하고 A.[[Status]] = B.[[Status]] = C.[[Status]] = unlinked 로 설정. 이후 A.Link() 호출도 성공(가정)하여 세 모듈 모두 linked. 이러한 준비 단계는 언제든 수행 가능. 나중에 호스트가 모듈의 부작용 실행 시점이 되면 A.Evaluate() 호출 → 성공적으로 완료, undefined 로 resolve 되는 Promise 반환(가정), 먼저 C 그다음 B 를 평가. 이 시점에 각 모듈 [[Status]]evaluated.

다음으로 링크 오류 사례: A.LoadRequestedModules() 성공 후 InnerModuleLinking(C) 는 성공하지만 그 뒤 B 에서 실패(예: C 가 제공하지 않는 것을 import). 그러면 원래 A.Link() 가 실패하고 AB[[Status]]unlinked 유지. Clinked 로 전이되어 있음.

마지막으로 링크 성공 후 평가 오류: InnerModuleEvaluation(C) 는 성공하지만 그 뒤 B 가 실패(예: B 코드에서 예외). 원래 A.Evaluate() 는 reject 된 Promise 반환으로 실패. 예외는 A, B[[EvaluationError]] 에 기록되고 두 모듈 [[Status]]evaluated. Cevaluated 되지만 예외 없이 성공 평가. 예외 저장을 통해 이후 Evaluate() 재호출 시 동일 예외 일관 제공. (호스트Cyclic Module Record 재사용 의무 없음; 예외 객체 노출 의무도 없음. 명세는 가능성만 제공.)

이제 다른 오류 조건 유형:

Figure 3: 해결 불가 모듈을 가진 그래프
모듈 A 가 ??? 로 표시된 존재하지 않는 모듈에 의존

이 시나리오에서 A 는 다른 모듈을 선언적 의존하지만 해당 Module Record 가 없음 (HostLoadImportedModuleFinishLoadingImportedModule 호출 시 예외 전달). 리소스 부재, 혹은 존재하지만 ParseModule 이 오류 반환 등 다양한 이유. 호스트는 실패 원인을 FinishLoadingImportedModule 에 전달하는 completion 을 통해 노출 선택 가능. 이 예외로 로딩 실패 → A.[[Status]]new 유지.

로딩 / 링크 / 평가 오류 차이는 다음 특징 때문:

  • 평가는 부작용이 있을 수 있어 한 번만 수행해야 하므로(비성공 포함) 이미 수행 여부 기억 필요. (오류 시에도 이후 Evaluate() 마다 새로운 예외 합성 대신 기존 예외 기억이 합리적)
  • 링크는 부작용이 없으므로 실패해도 나중에 재시도 가능
  • 로딩은 호스트와 긴밀히 상호작용하므로 일부 호스트는 실패한 로드 재시도 허용이 바람직(예: 일시적 네트워크 문제)

이제 순환이 있는 그래프:

Figure 4: 순환 모듈 그래프
모듈 A 가 B, C 에 의존하고 B 가 A 에도 의존

엔트리 포인트가 A 라 가정하고 호스트A.LoadRequestedModules() 호출 → A 에 대해 InnerModuleLoading 수행. 이는 B, C 에 대해 InnerModuleLoading 호출. 순환 때문에 다시 A 에 대해 InnerModuleLoading 트리거되지만 이미 로딩 트리거 되었으므로 no-op. 그래프 모든 모듈 로딩 성공 시 [[Status]] 는 동시에 newunlinked.

그 후 A.Link() → A 에 대해 InnerModuleLinkingB → 순환으로 다시 A (이미 linking 이므로 no-op). B 는 여전히 linking 상태에서 제어가 A 로 돌아와 C 에 대해 InnerModuleLinking. ClinkedA, B 가 함께 linkinglinked 전이; 이는 SCC 단위 동시 전이를 설계한 것. DFS 로 그래프 순회하므로 가능.

성공 사례에서 평가 단계도 유사.

A 에 링크 오류(예: C 에 존재하지 않는 바인딩 import) 인 경우 위 단계 진행 중 두 번째 InnerModuleLinking(A) 조기 반환 포함. 하지만 원래 InnerModuleLinking(A) 로 되돌아왔을 때 InitializeEnvironment 중 (C.ResolveExport() 직후) 실패, SyntaxError 전파 → A.Link 에서 현재 stack 에 있는(linking) 모듈 상태를 재설정. 따라서 A, Bunlinked, Clinked 유지.

유사하게 A 평가 오류(예: 코드 예외) 인 경우에도 평가 시퀀스는 비슷. 두 번째 InnerModuleEvaluation(A) 조기 반환 후 원래 InnerModuleEvaluation(A) 로 돌아와 실패. 예외가 A.Evaluate() 로 전파되어 현재 stack (여전히 evaluating) 및 [[AsyncParentModules]] 체인을 따라(상위 top-level await 를 가진 모듈 경유) AsyncModuleExecutionRejected 알고리즘으로 전파. 결과로 A, Bevaluated & 예외 기록, C 는 예외 없이 evaluated.

마지막으로 모든 모듈이 비동기 완료하는 순환 그래프:

Figure 5: 비동기 순환 모듈 그래프
모듈 A 가 B, C 에 의존, B 는 D, C 는 D, E 에 의존, D 는 A 에 의존

로딩과 링크는 이전과 같고 모두 [[Status]] = linked.

A.Evaluate() 는 A, B, D 에 대해 InnerModuleEvaluation 수행 → 모두 evaluating. 다시 A 호출은 no-op. 이때 D.[[PendingAsyncDependencies]] = 0 → ExecuteAsyncModule(D) 호출 → D.ExecuteModule 새 PromiseCapability. B 로 unwind: B.[[PendingAsyncDependencies]] = 1, [[AsyncEvaluationOrder]] = 1. 다시 A 로: A.[[PendingAsyncDependencies]] = 1. 다음 A 의 의존 반복에서 C 평가 → D(no-op), E. E 는 의존 없고 순환 아님 → ExecuteAsyncModule(E) 즉시 호출 & stack 에서 제거. 다시 C 로 unwind: C.[[AsyncEvaluationOrder]] = 3. A 의 의존 루프 종료 후 A.[[AsyncEvaluationOrder]] = 4, SCC 전체 stack 제거하며 모두 evaluating-async. 이 시점 필드는 Table 46 참조.

Table 46: 초기 Evaluate() 후 모듈 필드
필드
모듈
A B C D E
[[DFSAncestorIndex]] 0 0 0 0 4
[[Status]] evaluating-async evaluating-async evaluating-async evaluating-async evaluating-async
[[AsyncEvaluationOrder]] 4 1 3 0 2
[[AsyncParentModules]] « » « A » « A » « B, C » « C »
[[PendingAsyncDependencies]] 2 (B, C) 1 (D) 2 (D, E) 0 0

E 가 먼저 실행 완료한다고 가정. AsyncModuleExecutionFulfilled 호출 → E.[[Status]] = evaluated, C.[[PendingAsyncDependencies]] = 1. 업데이트 필드는 Table 47.

Table 47: E 실행 완료 후 필드
필드
모듈
C E
[[DFSAncestorIndex]] 0 4
[[Status]] evaluating-async evaluated
[[AsyncEvaluationOrder]] 3 done
[[AsyncParentModules]] « A » « C »
[[PendingAsyncDependencies]] 1 (D) 0

다음으로 D 완료. AsyncModuleExecutionFulfilled 호출 → D.[[Status]] = evaluated. 실행 가능한 조상은 [[AsyncEvaluationOrder]] 1 의 B, 3 의 C → 순서상 B 먼저 처리: B.[[PendingAsyncDependencies]] = 0 → ExecuteAsyncModule(B) → 실행 시작. C.[[PendingAsyncDependencies]] 도 0 → C 실행 시작( B 에 await 있다면 병렬 가능). 업데이트 필드는 Table 48.

Table 48: D 실행 완료 후 필드
필드
모듈
B C D
[[DFSAncestorIndex]] 0 0 0
[[Status]] evaluating-async evaluating-async evaluated
[[AsyncEvaluationOrder]] 1 3 done
[[AsyncParentModules]] « A » « A » « B, C »
[[PendingAsyncDependencies]] 0 0 0

C 가 다음으로 완료. AsyncModuleExecutionFulfilledC.[[Status]] = evaluated, A.[[PendingAsyncDependencies]] = 1. 필드는 Table 49.

Table 49: C 실행 완료 후 필드
필드
모듈
A C
[[DFSAncestorIndex]] 0 0
[[Status]] evaluating-async evaluated
[[AsyncEvaluationOrder]] 4 done
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 1 (B) 0

그 후 B 완료. AsyncModuleExecutionFulfilledB.[[Status]] = evaluated, A.[[PendingAsyncDependencies]] = 0 → ExecuteAsyncModule 호출 → 실행 시작. 필드는 Table 50.

Table 50: B 실행 완료 후 필드
필드
모듈
A B
[[DFSAncestorIndex]] 0 0
[[Status]] evaluating-async evaluated
[[AsyncEvaluationOrder]] 4 done
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 0 0

마지막으로 A 완료. AsyncModuleExecutionFulfilledA.[[Status]] = evaluated, A.[[TopLevelCapability]] 의 Promise(resolve) → 그래프 처리 종료. 필드는 Table 51.

Table 51: A 실행 완료 후 필드
필드
모듈
A
[[DFSAncestorIndex]] 0
[[Status]] evaluated
[[AsyncEvaluationOrder]] done
[[AsyncParentModules]] « »
[[PendingAsyncDependencies]] 0

대안: CB 완료 전 오류로 실패. AsyncModuleExecutionRejected 호출 → C.[[Status]] = evaluated, C.[[EvaluationError]] = 오류. 그런 다음 AsyncParentModules 전파. 필드는 Table 52.

Table 52: C 오류 완료 후 필드
필드
모듈
A C
[[DFSAncestorIndex]] 0 0
[[Status]] evaluated evaluated
[[AsyncEvaluationOrder]] done done
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 1 (B) 0
[[EvaluationError]] empty C 의 평가 오류

CA 에 대해 AsyncModuleExecutionRejected 호출하므로 A 는 동일 오류로 reject. A.[[Status]] = evaluated. A.[[TopLevelCapability]] Promise 는 reject. 필드는 Table 53.

Table 53: A 가 reject 된 후 필드
필드
모듈
A
[[DFSAncestorIndex]] 0
[[Status]] evaluated
[[AsyncEvaluationOrder]] done
[[AsyncParentModules]] « »
[[PendingAsyncDependencies]] 0
[[EvaluationError]] C 의 Evaluation Error

이후 B 가 오류 없이 완료. AsyncModuleExecutionFulfilledB.[[Status]] = evaluated. GatherAvailableAncestors(B) 호출. 그러나 A.[[CycleRoot]] = A, 그리고 평가 오류 존재 → sortedExecList 에 추가되지 않고 추가 처리 없이 반환. 이후 B 의 importer 는 cycle root A[[EvaluationError]] 를 통해 reject 를 해석. 필드는 Table 54.

Table 54: 오류 그래프에서 B 완료 후 필드
필드
모듈
A B
[[DFSAncestorIndex]] 0 0
[[Status]] evaluated evaluated
[[AsyncEvaluationOrder]] 4 1
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 0 0
[[EvaluationError]] C 의 Evaluation Error empty

16.2.1.7 소스 텍스트 모듈 레코드

Source Text Module RecordModule 목표 기호로 파싱된 ECMAScript 소스 텍스트 (11) 로 정의된 모듈 정보를 나타내는 데 사용된다. 필드는 모듈이 import/export 하는 이름에 대한 요약 정보를 포함하고, 구체 메서드는 이 요약을 사용해 링크 및 평가를 수행한다.

Source Text Module Record 는 추상 Module Record 타입의 다른 하위 클래스들과 같은 그래프에 존재할 수 있으며 Cyclic Module Record 타입의 다른 하위 클래스들과 순환에 참여할 수 있다.

Table 43 에 정의된 필드들 외에, Source Text Module RecordTable 55 에 있는 추가 필드를 가진다. 각 필드는 ParseModule 에서 초기화된다.

Table 55: Source Text Module Record 의 추가 필드
필드 이름 값 타입 의미
[[ECMAScriptCode]] Parse Node Module 을 목표 기호로 사용해 이 모듈 소스 텍스트를 파싱한 결과.
[[Context]] ECMAScript 코드 실행 컨텍스트 또는 empty 이 모듈에 연결된 실행 컨텍스트. 환경 초기화 전까지 empty.
[[ImportMeta]] Object 또는 empty import.meta 메타 프로퍼티로 노출되는 객체. ECMAScript 코드에서 접근 전까지 empty.
[[ImportEntries]] ImportEntry Record 리스트 이 모듈 코드에서 도출된 ImportEntry 리스트.
[[LocalExportEntries]] ExportEntry Record 리스트 모듈 내 선언에 해당하는 export 에 대한 ExportEntry 리스트.
[[IndirectExportEntries]] ExportEntry Record 리스트 모듈 내 재export(import 재export 또는 export * as namespace) 에 해당하는 ExportEntry 리스트.
[[StarExportEntries]] ExportEntry Record 리스트 모듈 내 export * 선언(단, export * as namespace 제외)에 해당하는 ExportEntry 리스트.

ImportEntry Record 는 단일 선언적 import 에 대한 정보를 요약한 Record. 각 ImportEntry RecordTable 56 필드를 가진다:

Table 56: ImportEntry Record 필드
필드 이름 값 타입 의미
[[ModuleRequest]] ModuleRequest Record ImportDeclarationModuleSpecifier 및 import 속성.
[[ImportName]] String 또는 namespace-object [[ModuleRequest]] 로 식별된 모듈이 해당 바인딩을 export 하는 이름. namespace-object 는 대상 모듈 네임스페이스 객체 import 요청을 의미.
[[LocalName]] String import 하는 모듈 내부에서 값에 접근할 때 사용하는 로컬 이름.
Note 1

Table 57 는 구문 import 형태를 표현하는 ImportEntry 필드 예시:

Table 57 (Informative): Import 문 형태와 ImportEntry 매핑
Import 문 형태 [[ModuleRequest]] [[ImportName]] [[LocalName]]
import v from "mod"; "mod" "default" "v"
import * as ns from "mod"; "mod" namespace-object "ns"
import {x} from "mod"; "mod" "x" "x"
import {x as v} from "mod"; "mod" "x" "v"
import "mod"; ImportEntry Record 생성 안 됨.

ExportEntry Record 는 단일 선언적 export 정보를 요약한 Record. 각 ExportEntry RecordTable 58 필드 보유:

Table 58: ExportEntry Record 필드
필드 이름 값 타입 의미
[[ExportName]] String 또는 null 모듈이 이 바인딩을 export 하는 이름.
[[ModuleRequest]] ModuleRequest Record 또는 null ExportDeclarationModuleSpecifier 및 import 속성을 나타내는 ModuleRequest Record. ModuleSpecifier 없으면 null.
[[ImportName]] String, null, all, 또는 all-but-default [[ModuleRequest]] 로 식별된 모듈이 해당 바인딩을 export 하는 이름. ModuleSpecifier 없으면 null. export * as ns from "mod"all, export * from "mod"all-but-default 사용.
[[LocalName]] String 또는 null importer 모듈 내부에서 export 값 접근 시 사용 로컬 이름. 로컬 접근 불가면 null.
Note 2

Table 59 는 구문 export 형태를 표현하는 ExportEntry 필드 예시:

Table 59 (Informative): Export 문 형태와 ExportEntry 매핑
Export 문 형태 [[ExportName]] [[ModuleRequest]] [[ImportName]] [[LocalName]]
export var v; "v" null null "v"
export default function f() {} "default" null null "f"
export default function () {} "default" null null "*default*"
export default 42; "default" null null "*default*"
export {x}; "x" null null "x"
export {v as x}; "x" null null "v"
export {x} from "mod"; "x" "mod" "x" null
export {v as x} from "mod"; "x" "mod" "v" null
export * from "mod"; null "mod" all-but-default null
export * as ns from "mod"; "ns" "mod" all null

다음 정의는 Source Text Module Record 에 필요한 구체 메서드와 기타 추상 연산을 명세한다.

16.2.1.7.1 ParseModule ( sourceText, realm, hostDefined )

The abstract operation ParseModule takes arguments sourceText (ECMAScript 소스 텍스트), realm (Realm Record), and hostDefined (anything) and returns Source Text Module Record 또는 SyntaxError 객체 비어있지 않은 리스트. sourceTextModule 로 파싱한 결과에 기반하여 Source Text Module Record 생성. It performs the following steps when called:

  1. body = ParseText(sourceText, Module).
  2. body 가 오류 리스트이면 body 반환.
  3. requestedModules = ModuleRequests(body).
  4. importEntries = ImportEntries(body).
  5. importedBoundNames = ImportedLocalNames(importEntries).
  6. indirectExportEntries = 새 빈 리스트.
  7. localExportEntries = 새 빈 리스트.
  8. starExportEntries = 새 빈 리스트.
  9. exportEntries = ExportEntries(body).
  10. ExportEntry Record eeexportEntries 에 대해
    1. ee.[[ModuleRequest]]null 이면
      1. importedBoundNamesee.[[LocalName]] 포함하지 않으면
        1. eelocalExportEntries 에 추가.
      2. Else
        1. ie = [[LocalName]]ee.[[LocalName]]importEntries 요소.
        2. ie.[[ImportName]]namespace-object 이면
          1. 참고: import 된 모듈 네임스페이스 객체 재export.
          2. eelocalExportEntries 에 추가.
        3. Else
          1. 참고: 단일 이름 재export.
          2. ExportEntry Record { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } 를 indirectExportEntries 에 추가.
    2. Else if ee.[[ImportName]]all-but-default 이면
      1. 단언: ee.[[ExportName]]null.
      2. eestarExportEntries 에 추가.
    3. Else
      1. eeindirectExportEntries 에 추가.
  11. async = body Contains await.
  12. Source Text Module Record { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[CycleRoot]]: empty, [[HasTLA]]: async, [[AsyncEvaluationOrder]]: unset, [[TopLevelCapability]]: empty, [[AsyncParentModules]]: « », [[PendingAsyncDependencies]]: empty, [[Status]]: new, [[EvaluationError]]: empty, [[HostDefined]]: hostDefined, [[ECMAScriptCode]]: body, [[Context]]: empty, [[ImportMeta]]: empty, [[RequestedModules]]: requestedModules, [[LoadedModules]]: « », [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries, [[IndirectExportEntries]]: indirectExportEntries, [[StarExportEntries]]: starExportEntries, [[DFSAncestorIndex]]: empty } 반환.
Note

구현은 ParseModule 평가 이전에 소스 텍스트를 파싱하고 Early Error 분석을 수행할 수 있으나 오류 보고는 실제 ParseModule 수행 시점까지 지연해야 한다.

16.2.1.7.2 Module Record 추상 메서드 구현

Table 42 에 정의된 Module Record 추상 메서드 구현을 위한 Source Text Module Record 의 구체 메서드.

16.2.1.7.2.1 GetExportedNames ( [ exportStarSet ] )

The GetExportedNames concrete method of Source Text Module Record module takes optional argument exportStarSet (Source Text Module Record 리스트) and returns 문자열 리스트. It performs the following steps when called:

  1. 단언: module.[[Status]]new 아님.
  2. exportStarSet 없으면 새 빈 리스트로 설정.
  3. exportStarSetmodule 포함하면
    1. 단언: export * 순환의 시작점 도달.
    2. 새 빈 리스트 반환.
  4. moduleexportStarSet 에 추가.
  5. exportedNames = 새 빈 리스트.
  6. module.[[LocalExportEntries]]ExportEntry Record e 에 대해
    1. 단언: module 이 직접 바인딩 제공.
    2. 단언: e.[[ExportName]]null 아님.
    3. e.[[ExportName]]exportedNames 에 추가.
  7. module.[[IndirectExportEntries]]e 에 대해
    1. 단언: module 이 특정 바인딩 import 후 재export.
    2. 단언: e.[[ExportName]]null 아님.
    3. e.[[ExportName]]exportedNames 에 추가.
  8. module.[[StarExportEntries]]e 에 대해
    1. 단언: e.[[ModuleRequest]]null 아님.
    2. requestedModule = GetImportedModule(module, e.[[ModuleRequest]]).
    3. starNames = requestedModule.GetExportedNames(exportStarSet).
    4. nstarNames 에 대해
      1. n"default" 이면
        1. exportedNamesn 포함하지 않으면 추가.
  9. exportedNames 반환.
Note

GetExportedNames 는 모호한 star export 바인딩 이름을 필터링하거나 예외를 던지지 않는다.

16.2.1.7.2.2 ResolveExport ( exportName [ , resolveSet ] )

The ResolveExport concrete method of Source Text Module Record module takes argument exportName (String) and optional argument resolveSet (Record 리스트 (필드 [[Module]]: Module Record, [[ExportName]]: String)) and returns ResolvedBinding Record, null, 또는 ambiguous.

ResolveExport 는 import 된 바인딩을 실제 정의 모듈과 로컬 바인딩 이름으로 해석. 정의 모듈은 자신 또는 import 된 다른 모듈일 수 있음. resolveSet 은 순환 import/export 경로 탐지를 위해 사용. 동일 Module RecordexportName 쌍이 이미 resolveSet 에 있으면 순환. 재귀 호출 전 { module, exportName } 쌍을 추가.

정의 모듈 발견 시 ResolvedBinding Record { [[Module]], [[BindingName]] } 반환(네임스페이스 export 만 있는 경우 [[BindingName]] = namespace). 정의 없거나 순환이면 null, 모호하면 ambiguous.

It performs the following steps when called:

  1. 단언: module.[[Status]]new 아님.
  2. resolveSet 없으면 새 빈 리스트.
  3. resolveSet 의 각 Record { [[Module]], [[ExportName]] } r 에 대해
    1. moduler.[[Module]] 동일이고 exportName = r.[[ExportName]] 이면
      1. 단언: 순환 import 요청.
      2. null 반환.
  4. Record { [[Module]]: module, [[ExportName]]: exportName } 를 resolveSet 에 추가.
  5. module.[[LocalExportEntries]]ExportEntry Record e 에 대해
    1. e.[[ExportName]] = exportName 이면
      1. 단언: 직접 바인딩 제공.
      2. ResolvedBinding Record { [[Module]]: module, [[BindingName]]: e.[[LocalName]] } 반환.
  6. module.[[IndirectExportEntries]]e 에 대해
    1. e.[[ExportName]] = exportName 이면
      1. 단언: e.[[ModuleRequest]]null.
      2. importedModule = GetImportedModule(module, e.[[ModuleRequest]]).
      3. e.[[ImportName]]all 이면
        1. 단언: 직접 바인딩 제공 안 함.
        2. ResolvedBinding Record { [[Module]]: importedModule, [[BindingName]]: namespace } 반환.
      4. Else
        1. 단언: 특정 바인딩 import 후 재export.
        2. 단언: e.[[ImportName]] 는 String.
        3. importedModule.ResolveExport(e.[[ImportName]], resolveSet) 반환.
  7. exportName = "default" 이면
    1. 단언: 명시적 default export 없음.
    2. null 반환.
    3. NOTE: export * from "mod"default export 제공 불가.
  8. starResolution = null.
  9. module.[[StarExportEntries]]e 에 대해
    1. 단언: e.[[ModuleRequest]]null.
    2. importedModule = GetImportedModule(module, e.[[ModuleRequest]]).
    3. resolution = importedModule.ResolveExport(exportName, resolveSet).
    4. resolution = ambiguous 이면 ambiguous 반환.
    5. resolutionnull 이면
      1. 단언: resolutionResolvedBinding Record.
      2. starResolutionnull 이면
        1. starResolution = resolution.
      3. Else
        1. 단언: 요청 이름을 포함하는 * import 가 하나 이상.
        2. resolution.[[Module]]starResolution.[[Module]] 이면 ambiguous 반환.
        3. resolution.[[BindingName]]starResolution.[[BindingName]] 이고 둘 중 하나가 namespace 이면 ambiguous.
        4. [[BindingName]] 이 모두 String 이고 다르면 ambiguous.
  10. starResolution 반환.

16.2.1.7.3 Cyclic Module Record 추상 메서드 구현

Table 44 에 정의된 Cyclic Module Record 추상 메서드를 구현하는 Source Text Module Record 의 구체 메서드.

16.2.1.7.3.1 InitializeEnvironment ( )

The InitializeEnvironment concrete method of Source Text Module Record module takes no arguments and returns unused 를 담은 정상 completion 또는 throw completion. It performs the following steps when called:

  1. module.[[IndirectExportEntries]] 의 각 ExportEntry Record e 에 대해
    1. 단언: e.[[ExportName]]null.
    2. resolution = module.ResolveExport(e.[[ExportName]]).
    3. resolutionnull 또는 ambiguous 이면 SyntaxError throw.
    4. 단언: resolutionResolvedBinding Record.
  2. 단언: module 의 모든 named export 는 해석 가능.
  3. realm = module.[[Realm]].
  4. 단언: realmundefined.
  5. env = NewModuleEnvironment(realm.[[GlobalEnv]]).
  6. module.[[Environment]] = env.
  7. module.[[ImportEntries]]ImportEntry Record in 에 대해
    1. importedModule = GetImportedModule(module, in.[[ModuleRequest]]).
    2. in.[[ImportName]]namespace-object 이면
      1. namespace = GetModuleNamespace(importedModule).
      2. env.CreateImmutableBinding(in.[[LocalName]], true) 수행.
      3. env.InitializeBinding(in.[[LocalName]], namespace) 수행.
    3. Else
      1. resolution = importedModule.ResolveExport(in.[[ImportName]]).
      2. resolutionnull 또는 ambiguous 이면 SyntaxError throw.
      3. resolution.[[BindingName]] = namespace 이면
        1. namespace = GetModuleNamespace(resolution.[[Module]]).
        2. env.CreateImmutableBinding(in.[[LocalName]], true).
        3. env.InitializeBinding(in.[[LocalName]], namespace).
      4. Else
        1. CreateImportBinding(env, in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]) 수행.
  8. moduleContext = 새 ECMAScript 코드 실행 컨텍스트.
  9. moduleContext.Function = null.
  10. 단언: module.[[Realm]]undefined.
  11. moduleContext.Realm = module.[[Realm]].
  12. moduleContext.ScriptOrModule = module.
  13. moduleContext.VariableEnvironment = module.[[Environment]].
  14. moduleContext.LexicalEnvironment = module.[[Environment]].
  15. moduleContext.PrivateEnvironment = null.
  16. module.[[Context]] = moduleContext.
  17. moduleContext 를 실행 컨텍스트 스택에 push; 실행 중 컨텍스트.
  18. code = module.[[ECMAScriptCode]].
  19. varDeclarations = VarScopedDeclarations(code).
  20. declaredVarNames = 새 빈 리스트.
  21. dvarDeclarations 에 대해
    1. BoundNames(d) 의 각 dn 에 대해
      1. declaredVarNamesdn 포함하지 않으면
        1. env.CreateMutableBinding(dn, false).
        2. env.InitializeBinding(dn, undefined).
        3. dndeclaredVarNames 에 추가.
  22. lexDeclarations = LexicallyScopedDeclarations(code).
  23. privateEnv = null.
  24. dlexDeclarations 에 대해
    1. BoundNames(d) 의 각 dn 에 대해
      1. IsConstantDeclaration(d) 가 true 이면
        1. env.CreateImmutableBinding(dn, true).
      2. Else
        1. env.CreateMutableBinding(dn, false).
      3. dFunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration 중 하나이면
        1. fo = InstantiateFunctionObject(d, env, privateEnv).
        2. env.InitializeBinding(dn, fo).
  25. moduleContext 를 실행 컨텍스트 스택에서 제거.
  26. unused 반환.

16.2.1.7.3.2 ExecuteModule ( [ capability ] )

The ExecuteModule concrete method of Source Text Module Record module takes optional argument capability (PromiseCapability Record) and returns unused 를 담은 정상 completion 또는 throw completion. It performs the following steps when called:

  1. moduleContext = 새 ECMAScript 코드 실행 컨텍스트.
  2. moduleContext.Function = null.
  3. moduleContext.Realm = module.[[Realm]].
  4. moduleContext.ScriptOrModule = module.
  5. 단언: 모듈이 링크되었고 환경 선언 인스턴스화 완료.
  6. moduleContext.VariableEnvironment = module.[[Environment]].
  7. moduleContext.LexicalEnvironment = module.[[Environment]].
  8. 실행 중 컨텍스트 suspend.
  9. module.[[HasTLA]] = false 이면
    1. 단언: capability 없음.
    2. moduleContext push → 실행 중 컨텍스트.
    3. result = Completion(Evaluation(module.[[ECMAScriptCode]]) ).
    4. moduleContext suspend 및 스택에서 제거.
    5. 최상위 컨텍스트 resume.
    6. resultabrupt completion 이면
      1. result 반환.
  10. Else
    1. 단언: capabilityPromiseCapability Record.
    2. AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext) 수행.
  11. unused 반환.

16.2.1.8 합성(Synthetic) 모듈 레코드

Synthetic Module Record 는 명세가 정의하는 모듈 정보를 나타내며 export 이름은 생성 시 정적으로 정의되고 값은 SetSyntheticModuleExport 로 시간에 따라 변경될 수 있다. import 또는 의존성이 없다.

Note
Synthetic Module Record 는 JSON 모듈, CSS 모듈 등 다양한 모듈 타입 정의에 사용 가능.

Table 41 의 필드 외에 Synthetic Module Record 는 Table 60 의 추가 필드를 가진다.

Table 60: Synthetic Module Record 의 추가 필드
필드 이름 값 타입 의미
[[ExportNames]] 문자열 리스트 모듈의 export 이름. 중복 없음.
[[EvaluationSteps]] Abstract Closure 모듈 평가 시 수행할 초기화 로직 (Synthetic Module Record 를 단일 인수). [[ExportNames]] 수정 금지. abrupt completion 반환 가능.

16.2.1.8.1 CreateDefaultExportSyntheticModule ( defaultExport )

The abstract operation CreateDefaultExportSyntheticModule takes argument defaultExport (ECMAScript 언어 값) and returns Synthetic Module Record. defaultExport 를 기본 export 로 하는 Synthetic Module Record 생성. It performs the following steps when called:

  1. realm = 현재 Realm Record.
  2. setDefaultExport = (module) 매개변수, defaultExport 캡처하는 Abstract Closure:
    1. SetSyntheticModuleExport(module, "default", defaultExport) 수행.
    2. NormalCompletion(unused) 반환.
  3. Synthetic Module Record { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[HostDefined]]: undefined, [[ExportNames]]: « "default" », [[EvaluationSteps]]: setDefaultExport } 반환.

16.2.1.8.2 ParseJSONModule ( source )

The abstract operation ParseJSONModule takes argument source (String) and returns Synthetic Module Record 를 담은 정상 completion 또는 throw completion. It performs the following steps when called:

  1. json = ? ParseJSON(source).
  2. CreateDefaultExportSyntheticModule(json) 반환.

16.2.1.8.3 SetSyntheticModuleExport ( module, exportName, exportValue )

The abstract operation SetSyntheticModuleExport takes arguments module (Synthetic Module Record), exportName (String), and exportValue (ECMAScript 언어 값) and returns unused. Synthetic Module Record 의 기존 export 값 설정/변경. It performs the following steps when called:

  1. 단언: module.[[ExportNames]]exportName 포함.
  2. envRec = module.[[Environment]].
  3. 단언: envRecempty.
  4. envRec.SetMutableBinding(exportName, exportValue, true) 수행.
  5. unused 반환.

16.2.1.8.4 Module Record 추상 메서드 구현

Table 42 에 정의된 Module Record 추상 메서드를 구현하는 Synthetic Module Record 의 구체 메서드.

16.2.1.8.4.1 LoadRequestedModules ( )

The LoadRequestedModules concrete method of Synthetic Module Record module takes no arguments and returns Promise. It performs the following steps when called:

  1. PromiseResolve(%Promise%, undefined) 반환.
Note
Synthetic Module Record 는 의존성이 없다.

16.2.1.8.4.2 GetExportedNames ( )

The GetExportedNames concrete method of Synthetic Module Record module takes no arguments and returns 문자열 리스트. It performs the following steps when called:

  1. module.[[ExportNames]] 반환.

16.2.1.8.4.3 ResolveExport ( exportName )

The ResolveExport concrete method of Synthetic Module Record module takes argument exportName (String) and returns ResolvedBinding Record 또는 null. It performs the following steps when called:

  1. module.[[ExportNames]]exportName 포함하지 않으면 null 반환.
  2. ResolvedBinding Record { [[Module]]: module, [[BindingName]]: exportName } 반환.

16.2.1.8.4.4 Link ( )

The Link concrete method of Synthetic Module Record module takes no arguments and returns unused 를 담은 정상 completion. It performs the following steps when called:

  1. realm = module.[[Realm]].
  2. env = NewModuleEnvironment(realm.[[GlobalEnv]]).
  3. module.[[Environment]] = env.
  4. module.[[ExportNames]] 의 각 String exportName 에 대해
    1. env.CreateMutableBinding(exportName, false).
    2. env.InitializeBinding(exportName, undefined).
  5. NormalCompletion(unused) 반환.

16.2.1.8.4.5 Evaluate ( )

The Evaluate concrete method of Synthetic Module Record module takes no arguments and returns Promise. It performs the following steps when called:

  1. moduleContext = 새 ECMAScript 코드 실행 컨텍스트.
  2. moduleContext.Function = null.
  3. moduleContext.Realm = module.[[Realm]].
  4. moduleContext.ScriptOrModule = module.
  5. moduleContext.VariableEnvironment = module.[[Environment]].
  6. moduleContext.LexicalEnvironment = module.[[Environment]].
  7. 실행 중 컨텍스트 suspend.
  8. moduleContext push → 실행 중 컨텍스트.
  9. steps = module.[[EvaluationSteps]].
  10. result = Completion(steps(module)).
  11. moduleContext suspend 및 스택에서 제거.
  12. 최상위 컨텍스트 resume.
  13. pc = ! NewPromiseCapability(%Promise%).
  14. IfAbruptRejectPromise(result, pc).
  15. Call(pc.[[Resolve]], undefined, « undefined ») 수행.
  16. pc.[[Promise]] 반환.

16.2.1.9 GetImportedModule ( referrer, request )

The abstract operation GetImportedModule takes arguments referrer (Cyclic Module Record) and request (ModuleRequest Record) and returns Module Record. It performs the following steps when called:

  1. recordsreferrer.[[LoadedModules]] 의 각 LoadedModuleRequest Record rModuleRequestsEqual(r, request) 이 true 인 것들의 리스트로 둔다.
  2. 단언: LoadRequestedModules 가 사전에 성공했으므로 records 는 정확히 한 요소.
  3. record = records 의 유일 요소.
  4. record.[[Module]] 반환.

16.2.1.10 HostLoadImportedModule ( referrer, moduleRequest, hostDefined, payload )

The host-defined abstract operation HostLoadImportedModule takes arguments referrer (Script Record, Cyclic Module Record, 또는 Realm Record), moduleRequest (ModuleRequest Record), hostDefined (anything), and payload (GraphLoadingState Record 또는 PromiseCapability Record) and returns unused.

Note 1

웹 브라우저 호스트 예: 사용자가 아래 컨트롤을 클릭할 때

<button type="button" onclick="import('./foo.mjs')">Click me</button>

import() 표현식 실행 시 활성 스크립트나 모듈이 없을 수 있다. 더 일반적으로 호스트가 ScriptOrModule 이 null 인 실행 컨텍스트를 스택에 푸시하는 상황이면 Realm Recordreferrer 가 될 수 있다.

HostLoadImportedModule 구현은 다음 요구사항을 따른다:

실제 과정은 호스트 정의이며 보통 적절한 Module Record 로드에 필요한 I/O 수행. 서로 다른 여러 (referrer, moduleRequest.[[Specifier]], moduleRequest.[[Attributes]]) 삼중 조합이 동일 Module Record 인스턴스에 매핑될 수 있음. 매핑 의미론은 호스트 정의이나 일반적으로 specifier 정규화 포함 (상대/축약 경로 확장 등).

Note 2

위 텍스트는 type: "json" 으로 import 하면 (그리고 HostLoadImportedModule 이 정상 완료) 호스트가 JSON 모듈 지원을 요구하지만 type: "json" 없이 import 할 때 JSON 모듈 지원을 금지하지 않는다.

16.2.1.11 FinishLoadingImportedModule ( referrer, moduleRequest, payload, result )

The abstract operation FinishLoadingImportedModule takes arguments referrer (Script Record, Cyclic Module Record, 또는 Realm Record), moduleRequest (ModuleRequest Record), payload (GraphLoadingState Record 또는 PromiseCapability Record), and result (Module Record 를 담은 정상 completion 또는 throw completion) and returns unused. It performs the following steps when called:

  1. result가 정상 completion이면
    1. referrer.[[LoadedModules]]ModuleRequestsEqual(record, moduleRequest)가 true인 LoadedModuleRequest Record record가 있으면
      1. 단언: record.[[Module]]result.[[Value]]는 동일한 Module Record이다.
    2. 그렇지 않으면
      1. LoadedModuleRequest Record { [[Specifier]]: moduleRequest.[[Specifier]], [[Attributes]]: moduleRequest.[[Attributes]], [[Module]]: result.[[Value]] }를 referrer.[[LoadedModules]]에 추가한다.
  2. payloadGraphLoadingState Record이면
    1. ContinueModuleLoading(payload, result)를 수행한다.
  3. 그렇지 않으면
    1. ContinueDynamicImport(payload, result)를 수행한다.
  4. unused를 반환한다.

16.2.1.12 AllImportAttributesSupported ( attributes )

The abstract operation AllImportAttributesSupported takes argument attributes (ImportAttribute Records 리스트) and returns Boolean. It performs the following steps when called:

  1. supportedHostGetSupportedImportAttributes()로 둔다.
  2. attributes의 각 ImportAttribute Record attribute에 대해
    1. supportedattribute.[[Key]]를 포함하지 않으면 false를 반환한다.
  3. true를 반환한다.

16.2.1.12.1 HostGetSupportedImportAttributes ( )

The host-defined abstract operation HostGetSupportedImportAttributes takes no arguments and returns 문자열 리스트. 호스트 환경이 지원하는 import attribute를 지정할 수 있게 한다. 지원되는 키를 가진 attribute만 호스트에 제공된다.

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

  • 지원되는 각 attribute를 나타내는 문자열의 리스트를 반환해야 한다.
  • 이 연산이 호출될 때마다 동일한 순서와 내용의 동일한 리스트를 반환해야 한다.

HostGetSupportedImportAttributes의 기본 구현은 새 빈 리스트를 반환하는 것이다.

Note
호스트가 처리할 attribute를 선택하도록 모든 attribute를 전달하는 대신 지원되는 attribute만 명시하게 하는 목적은 지원되지 않는 attribute가 서로 다른 호스트 간에도 일관되게 처리되도록 하기 위함이다.

16.2.1.13 GetModuleNamespace ( module )

The abstract operation GetModuleNamespace takes argument module (Module Record의 구체 하위 클래스 인스턴스) and returns Module Namespace Object. module의 export를 나타내는 Module Namespace Object를 가져온다. 처음 요청될 때 지연 생성하여 module.[[Namespace]]에 저장하고 이후 재사용한다. It performs the following steps when called:

  1. 단언: moduleCyclic Module Record라면 module.[[Status]]new 또는 unlinked가 아니다.
  2. namespacemodule.[[Namespace]]로 둔다.
  3. namespaceempty이면
    1. exportedNamesmodule.GetExportedNames()로 둔다.
    2. unambiguousNames를 새 빈 리스트로 둔다.
    3. exportedNames의 각 요소 name에 대해
      1. resolutionmodule.ResolveExport(name)로 둔다.
      2. resolutionResolvedBinding Record이면 nameunambiguousNames에 추가한다.
    4. namespaceModuleNamespaceCreate(module, unambiguousNames)로 설정한다.
  4. namespace를 반환한다.
Note

GetModuleNamespace는 예외를 던지지 않는다. 대신 이 시점에서 해결할 수 없는 이름은 네임스페이스에서 제외된다. 그러한 이름들은 어딘가에서 명시적으로 요청되지 않은 모호한 star export 전부가 아닌 한 이후 실제 링크 오류로 이어진다.

16.2.1.14 런타임 의미론: 평가

Module : [empty]
  1. undefined를 반환한다.
ModuleBody : ModuleItemList
  1. resultCompletion(Evaluation of ModuleItemList)로 둔다.
  2. result가 정상 completion이고 result.[[Value]]empty이면
    1. undefined를 반환한다.
  3. result를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. sl을 ? Evaluation of ModuleItemList로 둔다.
  2. sCompletion(Evaluation of ModuleItem)로 둔다.
  3. UpdateEmpty(s, sl)를 반환한다.
Note

ModuleItemList의 값은 그 ModuleItemList 안에서 마지막으로 값을 생성한 항목의 값이다.

ModuleItem : ImportDeclaration
  1. empty를 반환한다.

16.2.2 가져오기(Imports)

구문

ImportDeclaration : import ImportClause FromClause WithClauseopt ; import ModuleSpecifier WithClauseopt ; ImportClause : ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding , NameSpaceImport ImportedDefaultBinding , NamedImports ImportedDefaultBinding : ImportedBinding NameSpaceImport : * as ImportedBinding NamedImports : { } { ImportsList } { ImportsList , } FromClause : from ModuleSpecifier ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding ModuleExportName as ImportedBinding ModuleSpecifier : StringLiteral ImportedBinding : BindingIdentifier[~Yield, +Await] WithClause : with { } with { WithEntries ,opt } WithEntries : AttributeKey : StringLiteral AttributeKey : StringLiteral , WithEntries AttributeKey : IdentifierName StringLiteral

16.2.2.1 정적 의미론: 조기 오류

ModuleItem : ImportDeclaration
  • ImportDeclaration 의 BoundNames 에 중복 항목이 있으면 문법 오류이다.
WithClause : with { WithEntries ,opt }
  • WithClause 의 WithClauseToAttributes 결과에 a.[[Key]]b.[[Key]] 와 같은 서로 다른 항목 a, b 두 개가 있으면 문법 오류이다.

16.2.2.2 정적 의미론: ImportEntries : ImportEntry Record 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

Module : [empty]
  1. 새 빈 리스트를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. entries1ModuleItemList 의 ImportEntries 로 둔다.
  2. entries2ModuleItem 의 ImportEntries 로 둔다.
  3. entries1entries2 의 리스트 연결을 반환한다.
ModuleItem : ExportDeclaration StatementListItem
  1. 새 빈 리스트를 반환한다.
ImportDeclaration : import ImportClause FromClause WithClauseopt ;
  1. moduleImportDeclaration 의 ModuleRequests 의 유일한 요소로 둔다.
  2. ImportClause 의 ImportEntriesForModule(module) 를 반환한다.
ImportDeclaration : import ModuleSpecifier WithClauseopt ;
  1. 새 빈 리스트를 반환한다.

16.2.2.3 정적 의미론: ImportEntriesForModule : ImportEntry Record 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

ImportClause : ImportedDefaultBinding , NameSpaceImport
  1. entries1ImportedDefaultBinding 의 ImportEntriesForModule(module) 로 둔다.
  2. entries2NameSpaceImport 의 ImportEntriesForModule(module) 로 둔다.
  3. entries1entries2 의 리스트 연결을 반환한다.
ImportClause : ImportedDefaultBinding , NamedImports
  1. entries1ImportedDefaultBinding 의 ImportEntriesForModule(module) 로 둔다.
  2. entries2NamedImports 의 ImportEntriesForModule(module) 로 둔다.
  3. entries1entries2 의 리스트 연결을 반환한다.
ImportedDefaultBinding : ImportedBinding
  1. localNameImportedBinding 의 BoundNames 의 유일한 요소로 둔다.
  2. defaultEntryImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName } 로 둔다.
  3. « defaultEntry » 를 반환한다.
NameSpaceImport : * as ImportedBinding
  1. localNameImportedBinding 의 StringValue 로 둔다.
  2. entryImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: namespace-object, [[LocalName]]: localName } 로 둔다.
  3. « entry » 를 반환한다.
NamedImports : { }
  1. 새 빈 리스트를 반환한다.
ImportsList : ImportsList , ImportSpecifier
  1. specs1ImportsList 의 ImportEntriesForModule(module) 로 둔다.
  2. specs2ImportSpecifier 의 ImportEntriesForModule(module) 로 둔다.
  3. specs1specs2 의 리스트 연결을 반환한다.
ImportSpecifier : ImportedBinding
  1. localNameImportedBinding 의 BoundNames 의 유일한 요소로 둔다.
  2. entryImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName } 로 둔다.
  3. « entry » 를 반환한다.
ImportSpecifier : ModuleExportName as ImportedBinding
  1. importNameModuleExportName 의 StringValue 로 둔다.
  2. localNameImportedBinding 의 StringValue 로 둔다.
  3. entryImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName } 로 둔다.
  4. « entry » 를 반환한다.

16.2.2.4 정적 의미론: WithClauseToAttributes : ImportAttribute Record 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

WithClause : with { }
  1. 새 빈 리스트를 반환한다.
WithClause : with { WithEntries ,opt }
  1. attributesWithEntries 의 WithClauseToAttributes 로 둔다.
  2. attributes[[Key]] 필드 값을 UTF-16 코드 유닛 시퀀스로 간주한 사전식 순서에 따라 정렬한다. 참고: 이 정렬은 호스트가 열거 순서에 따라 동작을 바꾸지 못하도록 강제한다는 점에서만 관측 가능하다.
  3. attributes 를 반환한다.
WithEntries : AttributeKey : StringLiteral
  1. keyAttributeKey 의 PropName 으로 둔다.
  2. entry 를 ImportAttribute Record { [[Key]]: key, [[Value]]: StringLiteral 의 SV } 로 둔다.
  3. « entry » 를 반환한다.
WithEntries : AttributeKey : StringLiteral , WithEntries
  1. keyAttributeKey 의 PropName 으로 둔다.
  2. entry 를 ImportAttribute Record { [[Key]]: key, [[Value]]: StringLiteral 의 SV } 로 둔다.
  3. restWithEntries 의 WithClauseToAttributes 로 둔다.
  4. « entry » 와 rest 의 리스트 연결을 반환한다.

16.2.3 내보내기(Exports)

구문

ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ; export VariableStatement[~Yield, +Await] export Declaration[~Yield, +Await] export default HoistableDeclaration[~Yield, +Await, +Default] export default ClassDeclaration[~Yield, +Await, +Default] export default [lookahead ∉ { function, async [no LineTerminator here] function, class }] AssignmentExpression[+In, ~Yield, +Await] ; ExportFromClause : * * as ModuleExportName NamedExports NamedExports : { } { ExportsList } { ExportsList , } ExportsList : ExportSpecifier ExportsList , ExportSpecifier ExportSpecifier : ModuleExportName ModuleExportName as ModuleExportName

16.2.3.1 정적 의미론: 조기 오류

ExportDeclaration : export NamedExports ;
  • NamedExports 의 ReferencedBindings 에 StringLiteral 이 있으면 문법 오류이다.
  • NamedExports 의 ReferencedBindings 에 있는 각 IdentifierName n 에 대해: n 의 StringValue 가 ReservedWord 이거나 "implements", "interface", "let", "package", "private", "protected", "public", "static" 중 하나이면 문법 오류이다.
Note

위 규칙은 NamedExports 의 ReferencedBindings 각각이 IdentifierReference 로 취급됨을 의미한다.

16.2.3.2 정적 의미론: ExportedBindings : 문자열 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS.

Note

ExportedBindings 는 Module 의 ExportedNames 와 명시적으로 연결된 로컬 바인딩 이름들이다.

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. names1ModuleItemList 의 ExportedBindings 로 둔다.
  2. names2ModuleItem 의 ExportedBindings 로 둔다.
  3. names1names2 의 리스트 연결을 반환한다.
ModuleItem : ImportDeclaration StatementListItem
  1. 새 빈 리스트를 반환한다.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. 새 빈 리스트를 반환한다.
ExportDeclaration : export NamedExports ;
  1. NamedExports 의 ExportedBindings 를 반환한다.
ExportDeclaration : export VariableStatement
  1. VariableStatement 의 BoundNames 를 반환한다.
ExportDeclaration : export Declaration
  1. Declaration 의 BoundNames 를 반환한다.
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. ExportDeclaration 의 BoundNames 를 반환한다.
NamedExports : { }
  1. 새 빈 리스트를 반환한다.
ExportsList : ExportsList , ExportSpecifier
  1. names1ExportsList 의 ExportedBindings 로 둔다.
  2. names2ExportSpecifier 의 ExportedBindings 로 둔다.
  3. names1names2 의 리스트 연결을 반환한다.
ExportSpecifier : ModuleExportName
  1. ModuleExportName 의 StringValue 한 요소만 갖는 리스트를 반환한다.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. 첫 번째 ModuleExportName 의 StringValue 한 요소만 갖는 리스트를 반환한다.

16.2.3.3 정적 의미론: ExportedNames : 문자열 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS.

Note

ExportedNames 는 Module 이 로컬 바인딩 이름 중 하나에 명시적으로 매핑하는 외부로 보이는 이름들이다.

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. names1ModuleItemList 의 ExportedNames 로 둔다.
  2. names2ModuleItem 의 ExportedNames 로 둔다.
  3. names1names2 의 리스트 연결을 반환한다.
ModuleItem : ExportDeclaration
  1. ExportDeclaration 의 ExportedNames 를 반환한다.
ModuleItem : ImportDeclaration StatementListItem
  1. 새 빈 리스트를 반환한다.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. ExportFromClause 의 ExportedNames 를 반환한다.
ExportFromClause : *
  1. 새 빈 리스트를 반환한다.
ExportFromClause : * as ModuleExportName
  1. ModuleExportName 의 StringValue 한 요소만 갖는 리스트를 반환한다.
ExportFromClause : NamedExports
  1. NamedExports 의 ExportedNames 를 반환한다.
ExportDeclaration : export VariableStatement
  1. VariableStatement 의 BoundNames 를 반환한다.
ExportDeclaration : export Declaration
  1. Declaration 의 BoundNames 를 반환한다.
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. « "default" » 를 반환한다.
NamedExports : { }
  1. 새 빈 리스트를 반환한다.
ExportsList : ExportsList , ExportSpecifier
  1. names1ExportsList 의 ExportedNames 로 둔다.
  2. names2ExportSpecifier 의 ExportedNames 로 둔다.
  3. names1names2 의 리스트 연결을 반환한다.
ExportSpecifier : ModuleExportName
  1. ModuleExportName 의 StringValue 한 요소만 갖는 리스트를 반환한다.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. 두 번째 ModuleExportName 의 StringValue 한 요소만 갖는 리스트를 반환한다.

16.2.3.4 정적 의미론: ExportEntries : ExportEntry Record 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

Module : [empty]
  1. 새 빈 리스트를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. entries1ModuleItemList 의 ExportEntries 로 둔다.
  2. entries2ModuleItem 의 ExportEntries 로 둔다.
  3. entries1entries2 의 리스트 연결을 반환한다.
ModuleItem : ImportDeclaration StatementListItem
  1. 새 빈 리스트를 반환한다.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. moduleExportDeclaration 의 ModuleRequests 의 유일한 요소로 둔다.
  2. ExportFromClause 의 ExportEntriesForModule(module) 를 반환한다.
ExportDeclaration : export NamedExports ;
  1. NamedExports 의 ExportEntriesForModule(null) 를 반환한다.
ExportDeclaration : export VariableStatement
  1. entries 를 새 빈 리스트로 둔다.
  2. namesVariableStatement 의 BoundNames 로 둔다.
  3. namenames 에 대해
    1. ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } 를 entries 에 추가한다.
  4. entries 를 반환한다.
ExportDeclaration : export Declaration
  1. entries 를 새 빈 리스트로 둔다.
  2. namesDeclaration 의 BoundNames 로 둔다.
  3. namenames 에 대해
    1. ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } 를 entries 에 추가한다.
  4. entries 를 반환한다.
ExportDeclaration : export default HoistableDeclaration
  1. namesHoistableDeclaration 의 BoundNames 로 둔다.
  2. localNamenames 의 유일한 요소로 둔다.
  3. 유일 요소가 새 ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } 인 리스트를 반환한다.
ExportDeclaration : export default ClassDeclaration
  1. namesClassDeclaration 의 BoundNames 로 둔다.
  2. localName 을 그 유일한 요소로 둔다.
  3. 유일 요소가 새 ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } 인 리스트를 반환한다.
ExportDeclaration : export default AssignmentExpression ;
  1. entryExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: "*default*", [[ExportName]]: "default" } 로 둔다.
  2. « entry » 를 반환한다.
Note

"*default*" 는 익명 default export 값을 위한 명세 내부의 합성 이름이다. 더 자세한 내용은 이 노트 를 참조.

16.2.3.5 정적 의미론: ExportEntriesForModule : ExportEntry Record 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

ExportFromClause : *
  1. entryExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all-but-default, [[LocalName]]: null, [[ExportName]]: null } 로 둔다.
  2. « entry » 를 반환한다.
ExportFromClause : * as ModuleExportName
  1. exportNameModuleExportName 의 StringValue 로 둔다.
  2. entryExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all, [[LocalName]]: null, [[ExportName]]: exportName } 로 둔다.
  3. « entry » 를 반환한다.
NamedExports : { }
  1. 새 빈 리스트를 반환한다.
ExportsList : ExportsList , ExportSpecifier
  1. specs1ExportsList 의 ExportEntriesForModule(module) 로 둔다.
  2. specs2ExportSpecifier 의 ExportEntriesForModule(module) 로 둔다.
  3. specs1specs2 의 리스트 연결을 반환한다.
ExportSpecifier : ModuleExportName
  1. sourceNameModuleExportName 의 StringValue 로 둔다.
  2. modulenull 이면
    1. localName = sourceName.
    2. importName = null.
  3. 그렇지 않으면
    1. localName = null.
    2. importName = sourceName.
  4. 유일 요소가 새 ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: sourceName } 인 리스트를 반환한다.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. sourceName 을 첫 번째 ModuleExportName 의 StringValue 로 둔다.
  2. exportName 을 두 번째 ModuleExportName 의 StringValue 로 둔다.
  3. modulenull 이면
    1. localName = sourceName.
    2. importName = null.
  4. 그렇지 않으면
    1. localName = null.
    2. importName = sourceName.
  5. 유일 요소가 새 ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: exportName } 인 리스트를 반환한다.

16.2.3.6 정적 의미론: ReferencedBindings : Parse Node 리스트

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

NamedExports : { }
  1. 새 빈 리스트를 반환한다.
ExportsList : ExportsList , ExportSpecifier
  1. names1ExportsList 의 ReferencedBindings 로 둔다.
  2. names2ExportSpecifier 의 ReferencedBindings 로 둔다.
  3. names1names2 의 리스트 연결을 반환한다.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. 첫 번째 ModuleExportName 의 ReferencedBindings 를 반환한다.
ModuleExportName : IdentifierName
  1. 유일한 요소가 그 IdentifierName 인 리스트를 반환한다.
ModuleExportName : StringLiteral
  1. 유일한 요소가 그 StringLiteral 인 리스트를 반환한다.

16.2.3.7 런타임 의미론: 평가

ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ;
  1. empty 를 반환한다.
ExportDeclaration : export VariableStatement
  1. VariableStatement 의 Evaluation 결과를 ? 로 반환한다.
ExportDeclaration : export Declaration
  1. Declaration 의 Evaluation 결과를 ? 로 반환한다.
ExportDeclaration : export default HoistableDeclaration
  1. HoistableDeclaration 의 Evaluation 결과를 ? 로 반환한다.
ExportDeclaration : export default ClassDeclaration
  1. valueClassDeclaration 의 BindingClassDeclarationEvaluation 결과(? )로 둔다.
  2. classNameClassDeclaration 의 BoundNames 의 유일한 요소로 둔다.
  3. className"*default*" 이면
    1. env 를 실행 중 실행 컨텍스트의 LexicalEnvironment 로 둔다.
    2. InitializeBoundName("*default*", value, env) 를 수행한다.
  4. empty 를 반환한다.
ExportDeclaration : export default AssignmentExpression ;
  1. IsAnonymousFunctionDefinition(AssignmentExpression) 이 true 이면
    1. value 를 ? NamedEvaluation(AssignmentExpression, "default") 로 둔다.
  2. 그렇지 않으면
    1. rhs 를 ? Evaluation(AssignmentExpression) 로 둔다.
    2. value 를 ? GetValue(rhs) 로 둔다.
  3. env 를 실행 중 실행 컨텍스트의 LexicalEnvironment 로 둔다.
  4. InitializeBoundName("*default*", value, env) 를 수행한다.
  5. empty 를 반환한다.