このページはECMAScript® 2020 Language Specification15 ECMAScript Language: Scripts and Modules章をJavaScriptの学習目的で私的に日本語訳したものであり、直訳と意訳および推測が混在しています。そのため内容については正確ではない可能性があります。正確な情報を知りたい場合は、原文をご覧ください。また一部訳者によるコメントが含まれていることがあります。※このサイトの内容で損害や不利益を受けたとしても当方は一切の責任を負いません。

15.1 スクリプト(Scripts)

構文:

ScriptBody :

StatementList[~Yield, ~Await, ~Return]

15.1.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)

  • ScriptBodyLexicallyDeclaredNames に重複する要素が含まれているなら、構文エラー
  • ScriptBodyLexicallyDeclaredNames のいずれかの要素が、 ScriptBodyVarDeclaredNames にもあるなら、構文エラー

15.1.2 静的セマンティクス(Static Semantics): IsStrict

  1. ScriptBodyScriptBody が存在し、 ディレクティブプロローグUse Strictディレクティブ が含まれているなら true を、含まれていないなら false を返す

15.1.3 静的セマンティクス(Static Semantics): LexicallyDeclaredNames

  1. StatementListTopLevelLexicallyDeclaredNames を返す
Scriptのトップレベルでは、関数宣言はレキシカル宣言ではなくvar宣言のように扱われます。

15.1.4 静的セマンティクス(Static Semantics): LexicallyScopedDeclarations

  1. StatementListTopLevelLexicallyScopedDeclarations を返す

15.1.5 静的セマンティクス(Static Semantics): VarDeclaredNames

  1. StatementListTopLevelVarDeclaredNames を返す

15.1.6 静的セマンティクス(Static Semantics): VarScopedDeclarations

  1. StatementListTopLevelVarScopedDeclarations を返す

15.1.7 ランタイムセマンティクス:評価(Runtime Semantics: Evaluation)

  1. NormalCompletion(undefined) を返す

15.1.8 スクリプトレコード(Script Records)

スクリプトレコード

スクリプトレコードは、評価されるスクリプトに関する情報をカプセル化します。 各スクリプトレコードには、表37にリストされているフィールドが含まれています。

表37: スクリプトレコードのフィールド
フィールド名 値の型 意味
[[Realm]] レルムレコード |
undefined
スクリプトを作成したレルム
まだ割り当てられていない場合はundefined
[[Environment]] レキシカル環境 |
undefined
スクリプトの最上位のバインディングを含むレキシカル環境
このフィールドは、スクリプトがインスタンス化されるときに設定されます。
[[ECMAScriptCode]] パースノード Scriptゴールシンボルとして使用して、
このスクリプトのソーステキストを解析した結果。
[[HostDefined]] 不特定
デフォルト値はundefined
スクリプトに関連付ける追加情報。
ホスト環境で使用するために予約されている

15.1.9 ParseScript ( sourceText, realm, hostDefined )

引数sourceTextrealmhostDefinedを使用した抽象操作ParseScriptは、sourceTextScriptとして解析した結果に基づいてスクリプトレコードを作成します。 ParseScriptは、次の手順を実行します。

  1. Assert: sourceTextECMAScriptソーステキスト
  2. Scriptゴールシンボルとして使用してsourceTextを解析する。解析が成功し、早期エラーがないなら、結果の解析ツリーをbody をする。 それ以外なら、解析エラーや早期エラーを表す1つ以上のSyntaxErrorオブジェクトのリスト body をする。 解析と早期エラー検出は、実装に依存する方法する場合がある。 解析エラーまたは早期エラーが複数ある場合、リスト内のエラーオブジェクトの数と順序は実装に依存する。ただし、少なくとも1つは必要。
  3. body が エラーの List なら、 body を返す
  4. スクリプトレコード { [[Realm]]: realm, [[Environment]]: undefined, [[ECMAScriptCode]]: body, [[HostDefined]]: hostDefined } を返す
実装は、スクリプトソーステキストを解析し、そのスクリプトソーステキストのParseScriptを評価する前に、早期エラー状態を分析する場合があります。 ただし、エラー報告は、この仕様が実際にそのソーステキストに対してParseScriptを実行する時点まで延期する必要があります。

15.1.10 ScriptEvaluation ( scriptRecord )

  1. scriptRecord.[[Realm]].[[GlobalEnv]] を globalEnv とする
  2. 新規 ECMAScriptコード実行コンテキストscriptContext とする
  3. nullscriptContextFunctionコンポーネント にセットする
  4. scriptRecordscriptContextRealmコンポーネント にセットする [[Realm]]
  5. scriptRecordscriptContextScriptOrModuleコンポーネント にセットする
  6. globalEnvscriptContextVariableEnvironmentコンポーネント にセットする
  7. globalEnvscriptContextLexicalEnvironmentコンポーネント にセットする
  8. 現在の実行中の実行コンテキストSuspendする
  9. scriptContext実行コンテキストスタックにプッシュする。scriptContext実行中の実行コンテキストになる
  10. scriptRecord.[[ECMAScriptCode]] を scriptBody とする
  11. GlobalDeclarationInstantiation(scriptBody, globalEnv) を result とする
  12. result.[[Type]] が normal なら、
    1. scriptBody の評価結果を result にセットする
  13. result.[[Type]] が normalresult.[[Value]] is empty なら、
    1. NormalCompletion(undefined) を result にセットする
  14. scriptContextSuspend し、実行コンテキストスタックから削除する
  15. Assert: 実行コンテキストスタックempty ではない
  16. 実行コンテキストスタックの最上位にあるコンテキストを実行中の実行コンテキストとして再開する
  17. Completion(result) を返す

15.1.11 ランタイムセマンティクス(Runtime Semantics): GlobalDeclarationInstantiation ( script, env )

スクリプトを評価するための実行コンテキストが確立されると、宣言は現在のグローバル環境でインスタンス化されます。 コードで宣言された各グローバルバインディングがインスタンス化されます。

GlobalDeclarationInstantiationは、引数scriptenvを使用して次のように実行されます。 scriptは、実行コンテキストが確立されているScriptBodyです。 envは、バインディングが作成されるグローバルなレキシカル環境です。

  1. envEnvironmentRecordenvRec とする
  2. Assert: envRecグローバル環境レコード
  3. scriptLexicallyDeclaredNameslexNames とする
  4. scriptVarDeclaredNamesvarNames とする
  5. lexNames の 各要素を name とし、name ごとに次を実行する
    1. envRec.HasVarDeclaration(name) が true なら、 SyntaxError例外をスローする
    2. envRec.HasLexicalDeclaration(name) が true なら、SyntaxError例外をスローする
    3. ? envRec.HasRestrictedGlobalProperty(name) を hasRestrictedGlobal とする
    4. hasRestrictedGlobaltrue なら、 SyntaxError例外をスローする
  6. varNames の 各要素を name とし、name ごとに次を実行する
    1. envRec.HasLexicalDeclaration(name) が true なら、SyntaxError例外をスローする
  7. scriptVarScopedDeclarationsvarDeclarations とする
  8. 空の新規ListfunctionsToInitialize とする
  9. 空の新規ListdeclaredFunctionNames とする
  10. varDeclarations 内の各要素を d とし、リストの逆順で次を実行する
    1. dVariableDeclarationForBindingBindingIdentifier のどれでないなら、
      1. Assert: dFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration のどれか
      2. NOTE: 同名の関数宣言は、最後の宣言が使用される
      3. dBoundNames の唯一の要素を fn とする
      4. fndeclaredFunctionNames の要素でないなら、
        1. ? envRec.CanDeclareGlobalFunction(fn) を fnDefinable とする
        2. fnDefinablefalse なら、 TypeError例外をスローする
        3. declaredFunctionNamesfn を追加する
        4. functionsToInitialize の最初に d を挿入する
  11. 空の新規ListdeclaredVarNames とする
  12. varDeclarations の 各要素を d とし、d ごとに次を実行する
    1. dVariableDeclarationForBindingBindingIdentifier なら、
      1. dBoundNames 内の文字列を vn とし、 vn ごとに次を実行する
        1. vndeclaredFunctionNames の要素でないなら、
          1. ? envRec.CanDeclareGlobalVar(vn) を vnDefinable とする
          2. vnDefinablefalse なら、 TypeError例外をスローする
          3. vndeclaredVarNames の要素でないなら、
            1. declaredVarNamesvn を追加する
  13. NOTE: グローバルオブジェクト通常のオブジェクト である場合、このアルゴリズムステップの後に異常終了は発生しません。 ただし、グローバルオブジェクトがProxyエキゾチックオブジェクト である場合、以降手順の一部で異常終了が発生する可能性があります
  14. NOTE: 付録B.3.3.2に、追加の手順あり
  15. scriptLexicallyScopedDeclarationslexDeclarations とする
  16. lexDeclarations の 各要素を d とし、d ごとに次を実行する
    1. NOTE: レキシカル宣言された名前は、ここではインスタンス化のみで、初期化されない
    2. dBoundNames の 各要素を dn とし、dn ごとに次を実行する
      1. dIsConstantDeclarationtrue なら、
        1. ? envRec.CreateImmutableBinding(dn, true) を実行する
      2. i. と異なるなら、
        1. ? envRec.CreateMutableBinding(dn, false) を実行する
  17. functionsToInitialize の 各要素を パースノード f とし、パースノード f ごとに次を実行する
    1. fBoundNames の唯一の要素を fn とする
    2. 引数 env を使用して fInstantiateFunctionObjectfo とする
    3. ? envRec.CreateGlobalFunctionBinding(fn, fo, false) を実行する
  18. declaredVarNames の 各文字列 を vn とし、各 vn をリスト順に次を実行する
    1. ? envRec.CreateGlobalVarBinding(vn, false) を実行する
  19. NormalCompletion(empty) を返す
15.1.1の早期エラーは、 function/var宣言とlet/const/class宣言間の名前の競合、および単一のScript内に含まれるlet/const/classの再宣言を防ぎます。 ただし、複数のScriptにまたがる競合と再宣言は、GlobalDeclarationInstantiationでランタイムエラーとして検出されます。 このエラーが検出されると、スクリプトのバインディングはインスタンス化されません。 ただし、グローバルオブジェクトがプロキシエキゾチックオブジェクトを使用して定義されている場合、競合する宣言のランタイムテストの信頼性が低くなり、結果として突然の完了し、一部のグローバル宣言がインスタンス化されない可能性があります。 この場合、スクリプトのコードは評価されません。

15.2 モジュール(Modules)

構文:

15.2.1 モジュールセマンティクス(Module Semantics)

15.2.1.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)

  • ModuleItemListLexicallyDeclaredNames に重複する要素が含まれているなら、構文エラー
  • ModuleItemListLexicallyDeclaredNames のいずれかの要素が、 ModuleItemListVarDeclaredNames にもあるなら、構文エラー
  • ModuleItemListExportedNames に重複する要素が含まれているなら、構文エラー
  • ModuleItemListExportedBindings の要素が、ModuleItemListVarDeclaredNames または ModuleItemListLexicallyDeclaredNames のどちらにも存在しないなら、構文エラー
  • ModuleItemList Contains super なら、構文エラー
  • ModuleItemList Contains NewTarget なら、構文エラー
  • 引数 « » を使用して ModuleItemListContainsDuplicateLabelstrue なら、構文エラー
  • 引数 « » を使用して ModuleItemListContainsUndefinedBreakTargettrue なら、構文エラー
  • 引数 « »« » を使用して ModuleItemListContainsUndefinedContinueTargettrue なら、構文エラー
ExportedNamesの重複は、ModuleBody内にexport defaultExportDeclarationアイテムが複数あり、構文エラーであることを意味します。 宣言が競合または重複するかどうかは、Module評価前(モジュールリンク中)にチェックされます。 このようなエラーが検出された場合、Moduleは評価されません。

15.2.1.2 静的セマンティクス(Static Semantics): ContainsDuplicateLabels

引数 labelSet を使用。

  1. 引数 labelSet を使用して ModuleItemListContainsDuplicateLabelshasDuplicates とする
  2. hasDuplicatestrue なら、 true を返す
  3. 引数 labelSet を使用して ModuleItemContainsDuplicateLabels の実行結果を返す
  1. false を返す

15.2.1.3 静的セマンティクス(Static Semantics): ContainsUndefinedBreakTarget

引数 labelSet を使用。

  1. 引数 labelSet を使用して ModuleItemListContainsUndefinedBreakTargethasUndefinedLabels とする
  2. hasUndefinedLabelstrue なら、 true を返す
  3. 引数 labelSet を使用して ModuleItemContainsUndefinedBreakTarget の実行結果を返す
  1. false を返す

15.2.1.4 静的セマンティクス(Static Semantics): ContainsUndefinedContinueTarget

引数 iterationSetlabelSet を使用。

  1. 引数 iterationSet« » を使用して ModuleItemListContainsUndefinedContinueTargethasUndefinedLabels とする
  2. hasUndefinedLabelstrue なら、 true を返す
  3. 引数 iterationSet« » を使用して ModuleItemContainsUndefinedContinueTarget の実行結果を返す
  1. false を返す

15.2.1.5 静的セマンティクス(Static Semantics): ExportedBindings

ExportedBindingsは、ModuleExportedNamesに明示的に関連付けられているローカルにバインドされた名前です。
  1. ModuleItemListExportedBindingsnames とする
  2. ModuleItemExportedBindings の要素を names に追加する
  3. names を返す
  1. 空の新規List を返す

15.2.1.6 静的セマンティクス(Static Semantics): ExportedNames

ExportedNamesは、Moduleがそのローカルの名前バインディングに明示的にマップすることで、外部から参照可能な名前です。
  1. ModuleItemListExportedNamesnames とする
  2. ModuleItemExportedNames の要素を names に追加する
  3. names を返す
  1. ExportDeclarationExportedNames を返す
  1. 空の新規List を返す

15.2.1.7 静的セマンティクス(Static Semantics): ExportEntries

  1. 空の新規List を返す
  1. ModuleItemListExportEntriesentries とする
  2. ModuleItemExportEntries の要素を entries に追加する
  3. entries を返す
  1. 空の新規List を返す

15.2.1.8 静的セマンティクス(Static Semantics): ImportEntries

  1. 空の新規List を返す
  1. ModuleItemListImportEntriesentries とする
  2. ModuleItemImportEntries の要素を entries に追加する
  3. entries を返す
  1. 空の新規List を返す

15.2.1.9 静的セマンティクス(Static Semantics): ImportedLocalNames ( importEntries )

引数importEntriesを指定した抽象操作ImportedLocalNamesは、ImportEntryレコードのリストによって定義されたすべてのローカルネームバインディングのリストを作成します(表43を参照)。 ImportedLocalNamesは、次の手順を実行します。

  1. 空の新規ListlocalNames とする
  2. importEntries の 各 ImportEntryレコードi とし、 i ごとに次を実行する
    1. localNamesi.[[LocalName]] を追加する
  3. localNames を返す

15.2.1.10 静的セマンティクス(Static Semantics): ModuleRequests

  1. 空の新規List を返す
  1. ModuleItemModuleRequests を返す
  1. ModuleItemListModuleRequestsmoduleNames とする
  2. ModuleItemModuleRequestsadditionalNames とする
  3. moduleNames に存在していない additionalNames の要素を moduleNames に追加する
  4. moduleNames を返す
  1. 空の新規List を返す

15.2.1.11 静的セマンティクス(Static Semantics): LexicallyDeclaredNames

ModuleLexicallyDeclaredNamesには、インポートされたすべてのバインディングの名前が含まれます。
  1. ModuleItemListLexicallyDeclaredNamesnames とする
  2. ModuleItemLexicallyDeclaredNames の要素を names に追加する
  3. names を返す
  1. ImportDeclarationBoundNames を返す
  1. ExportDeclarationexport VariableStatement なら、 空の新規List を返す
  2. ExportDeclarationBoundNames を返す
  1. StatementListItemLexicallyDeclaredNames を返す
Moduleのトップレベルでは、関数宣言はvar宣言ではなく、レキシカル宣言のように扱われます。

15.2.1.12 静的セマンティクス(Static Semantics): LexicallyScopedDeclarations

  1. 空の新規List を返す
  1. ModuleItemListLexicallyScopedDeclarationsdeclarations とする
  2. ModuleItemLexicallyScopedDeclarations の要素を declarations に追加する
  3. declarations を返す
  1. 空の新規List を返す

15.2.1.13 静的セマンティクス(Static Semantics): VarDeclaredNames

  1. 空の新規List を返す
  1. ModuleItemListVarDeclaredNamesnames とする
  2. ModuleItemVarDeclaredNames の要素を names に追加する
  3. names を返す
  1. 空の新規List を返す
  1. ExportDeclarationexport VariableStatement なら、 ExportDeclarationBoundNames を返す
  2. 空の新規List を返す

15.2.1.14 静的セマンティクス(Static Semantics): VarScopedDeclarations

  1. 空の新規List を返す
  1. ModuleItemListVarScopedDeclarationsdeclarations とする
  2. ModuleItemVarScopedDeclarations の要素を declarations に追加する
  3. declarations を返す
  1. 空の新規List を返す
  1. ExportDeclarationexport VariableStatement なら、 VariableStatementVarScopedDeclarations を返す
  2. 空の新規List を返す

15.2.1.15 抽象モジュールレコード(Abstract Module Records)

モジュールレコード

モジュールレコードは、単一モジュールのインポートとエクスポートに関する構造情報をカプセル化します。 この情報は、接続されたモジュールセットのインポートとエクスポートをリンクするために使用されます。 モジュールレコードには、モジュールを評価するときにのみ使用される4つのフィールドが含まれています。

仕様上、モジュールレコード値はRecord仕様型です。モジュールレコードが抽象サブクラスと具象サブクラスの両方を持つ抽象クラスである単純なオブジェクト指向階層に存在すると考えることができます。 この仕様は、Cyclicモジュールレコードという抽象サブクラスとソーステキストモジュールレコードという具象サブクラスを定義します。 他の仕様および実装では、定義した代替モジュール定義機能に対応する追加のモジュールレコードサブクラスを定義できます。

モジュールレコードは、表38にリストされているフィールドを持ちます。すべてのモジュール定義サブクラスは、これらのフィールドが含まれます。 モジュールレコードは、表39の抽象メソッドリストが定義されます。すべてのモジュール定義サブクラスは、これらのメソッドの具体的な実装を提供する必要があります。

表38: モジュールレコードフィールド
フィールド名 値の型 意味
[[Realm]] レルムレコード |
undefined
モジュールが作成されたレルム。 まだ割り当てられていない場合はundefined
[[Environment]] レキシカル環境 |
undefined
モジュールの最上位バインディングを含むレキシカル環境。 モジュールがリンクされているときに設定されます。
[[Namespace]] Object |
undefined
モジュール名前空間オブジェクト(26.3)(このモジュール用に作成されている場合)。 それ以外の場合はundefinedです。
[[HostDefined]] 不特定
デフォルトはundefined
モジュールに関連付けられた追加情報。ホスト環境で使用するために予約されたフィールド。
表39: モジュールレコードの抽象メソッド
メソッド 目的
GetExportedNames([exportStarSet]) モジュールから直接または間接的にエクスポートされたすべての名前リストを返します。
ResolveExport( exportName [, resolveSet]) モジュールによってエクスポートされた名前バインディングを返します。

ResolvedBindingレコード

バインディングは、{[[Module]]:モジュールレコード,[[BindingName]]:String}の形式のResolvedBindingレコードで表されます。 エクスポートがモジュールに直接バインドされていないモジュール名前空間オブジェクトの場合、[[BindingName]]は "*namespace*" が設定されます。 名前を解決できない場合はnullを返し、複数のバインディングが見つかった場合は "ambiguous" を返します。

この操作が 同じ引数で呼び出され、正常に完了した場合は同じ結果を返す必要があります。

Link() すべてのモジュール依存関係を推移的に解決し、モジュール環境レコードを作成して、評価のためのモジュールを準備します。
Evaluate() モジュールがすでに正常に評価されている場合は、undefinedを返します。 評価に失敗している場合は、生成された例外をスローします。 それ以外の場合は、このモジュールのすべてのモジュール依存関係を推移的に評価してから、モジュールを評価します。

このメソッドを呼び出す前に、リンクが正常に完了している必要があります。

15.2.1.16 Cyclicモジュールレコード(Cyclic Module Records)

Cyclicモジュールレコード

Cyclicモジュールレコードは、他のCyclicモジュールレコード型のサブクラスモジュールとの依存関係にあるモジュールに関する情報を保持します。
Cyclicモジュールレコードのサブクラスではないモジュールレコードは、ソーステキストモジュールレコードとの依存サイクルに参加してはなりません。

Cyclicモジュールレコードは、表38に加えて表40のフィールドを持ちます。

表40: Cyclicモジュールレコードの追加フィールド
フィールド名 値の型 意味
[[Status]] unlinked | linking |
linked | evaluating |
evaluated
初期値はunlinked。 モジュールがライフサイクル全体にわたって進行するにつれて、 linkinglinkedevaluatingevaluatedの順序で移行します。
[[EvaluationError]] 突然の完了 |
undefined
評価中に発生した例外を表すthrow型の完了。 例外が発生しなかった場合、または[[Status]]がevaluatedではない場合はundefinedです。
[[DFSIndex]] 整数 |
undefined
リンクおよび評価中にのみ使用される補助フィールド。 [[Status]]が linking または evaluating のとき、この負でないの数値は、依存関係グラフの進行中の深さ優先走査中にモジュールが最初にアクセスされたポイントを記録します。
[[DFSAncestorIndex]] 整数 |
undefined
リンクおよび評価中にのみ使用される補助フィールド。 [[Status]]が linking または evaluating のとき、モジュール自体の[[DFSIndex]]か、同じ強連結成分内の "earlier" モジュールの[[DFSIndex]]です。
[[RequestedModules]] String のリスト モジュールのインポートを要求するために、モジュールによって使用されるすべてのModuleSpecifier文字列のリスト。 リストは、ソースコードの出現順序です。

Cyclicモジュールレコードは、表39に加えて表41のメソッドを持ちます。

表41: Cyclicモジュールレコードの追加抽象メソッド
メソッド 意味
InitializeEnvironment() インポートされたすべてのバインディングの解決を含め、モジュールのレキシカル環境を初期化し、モジュールの実行コンテキストを作成します。
ExecuteModule() 実行コンテキスト内でモジュールのコードを評価します。
15.2.1.16.1 Link ( ) 具象メソッド(Concrete Method)

Cyclicモジュールレコード の Link具象メソッドは、対応するモジュールレコード抽象メソッドを実装します。

成功すると、Link はモジュールの [[Status]] を unlinked から linked に変更します。 失敗すると、例外がスローされ、モジュールの [[Status]] は unlinked のままになります。

この抽象メソッドは、次の手順を実行します(ほとんどの作業は補助関数InnerModuleLinkingによって実行されます)。

  1. Cyclicモジュールレコードmodule とする
  2. Assert: module.[[Status]] は linkingevaluating ではない
  3. 空の新規Liststack とする
  4. InnerModuleLinking(module, stack, 0) を result とする
  5. result突然の完了 なら、
    1. stack の 各 Cyclicモジュールレコードm とし、m ごとに次を実行する
      1. Assert: m.[[Status]] は linking
      2. unlinkedm.[[Status]] にセットする
      3. undefinedm.[[Environment]] にセットする
      4. undefinedm.[[DFSIndex]] にセットする
      5. undefinedm.[[DFSAncestorIndex]] にセットする
    2. Assert: module.[[Status]] は unlinked
    3. result を返す
  6. Assert: module.[[Status]] は linkedevaluated
  7. Assert: stackempty
  8. undefined を返す
15.2.1.16.1.1 InnerModuleLinking ( module, stack, index )

InnerModuleLinking抽象操作は、Linkから呼び出されます。Cyclicモジュールレコードmodule の実際のリンクプロセスを実行します。また、依存関係グラフ内の他のすべてのモジュールに対して再帰的に実行します。 stackindex、および<モジュールの[[DFSIndex]]フィールドと[[DFSAncestorIndex]]フィールドは、深さ優先探索(DFS)トラバーサルを追跡します。 特に、[[DFSAncestorIndex]]は、強連結成分(SCC)内のすべてのモジュールが相互にリンクさせるために、SCCを検出する目的で使用されます。

この抽象操作は、次の手順を実行します。

  1. module が a Cyclicモジュールレコード でないなら、
    1. ? module.Link() を実行する
    2. index を返す
  2. module.[[Status]] が linkinglinkedevaluated なら、
    1. index を返す
  3. Assert: module.[[Status]] は unlinked
  4. linkingmodule.[[Status]] にセットする
  5. indexmodule.[[DFSIndex]] にセットする
  6. indexmodule.[[DFSAncestorIndex]] にセットする
  7. index + 1 を index にセットする
  8. stackmodule を追加する
  9. module.[[RequestedModules]] の 各文字列要素を required とし、required ごとに次を実行する
    1. ? HostResolveImportedModule(module, required) を requiredModule とする
    2. ? InnerModuleLinking(requiredModule, stack, index) を index にセットする
    3. requiredModuleCyclicモジュールレコード なら、
      1. Assert: requiredModule.[[Status]] は linkinglinkedevaluated のどれか
      2. Assert: requiredModule.[[Status]] は requiredModulestack にある場合にのみ linking
      3. requiredModule.[[Status]] が linking なら、
        1. min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]) を module.[[DFSAncestorIndex]] にセットする
  10. ? module.InitializeEnvironment() を実行する
  11. Assert: modulestack で1回のみ発生
  12. Assert: module.[[DFSAncestorIndex]] は module.[[DFSIndex]] 以下
  13. module.[[DFSAncestorIndex]] イコール module.[[DFSIndex]] なら、
    1. falsedone とする
    2. donefalse に間繰り返す
      1. stack の最後の要素を requiredModule とする
      2. stack の最後の要素を削除する
      3. Assert: requiredModuleCyclicモジュールレコード
      4. linkedrequiredModule.[[Status]] にセットする
      5. requiredModulemodule が 同じモジュールレコード なら、 truedone にセットする
  14. index を返す
15.2.1.16.2 Evaluate ( ) 具象メソッド(Concrete Method)

Cyclicモジュールレコードの具体的な評価メソッドは、対応するモジュールコード抽象メソッドを実装します。Evaluateはモジュールの[[Status]]を linked から evaluated に変更します。例外が発生した場合、その例外が[[EvaluationError]]フィールドに記録され、Evaluateが再度呼び出されたとき再度スローされます。
この抽象メソッドは、次の手順を実行します(ほとんどの作業は補助関数InnerModuleEvaluationによって実行されます)。

  1. Assert: Evaluate呼び出しは、同時に周囲のエージェント内で呼び出されていない
  2. Cyclicモジュールレコードmodule とする
  3. Assert: module.[[Status]] は linked または evaluated
  4. 空の新規Liststack とする
  5. InnerModuleEvaluation(module, stack, 0) を result とする
  6. result突然の完了 なら、
    1. stack の 各要素を Cyclicモジュールレコード m とし、 Cyclicモジュールレコード m ごとに次を実行する
      1. Assert: m.[[Status]] は evaluating
      2. evaluatedm.[[Status]] にセットする
      3. resultm.[[EvaluationError]] にセットする
    2. Assert: module.[[Status]] は evaluatedmodule.[[EvaluationError]] は result
    3. result を返す
  7. Assert: module.[[Status]] は evaluatedmodule.[[EvaluationError]] は undefined
  8. Assert: stackempty
  9. undefined を返す
15.2.1.16.2.1 InnerModuleEvaluation ( module, stack, index )

InnerModuleEvaluation抽象操作は、Evaluateから呼び出されます。ソーステキストモジュールレコード moduleの実際の評価プロセスを実行するだけでなく、依存関係グラフ内の他のすべてのモジュールに対して再帰的に実行されます。 stackindex、およびmoduleの[[DFSIndex]]フィールドと[[DFSAncestorIndex]]フィールドは、InnerModuleLinkingと同じ方法で使用されます。

  1. moduleCyclicモジュールレコード でないなら、
    1. ? module.Evaluate() を実行する
    2. index を返す
  2. module.[[Status]] が evaluated なら、
    1. module.[[EvaluationError]] が undefined なら、 index を返す
    2. module.[[EvaluationError]] を返す
  3. module.[[Status]] が evaluating なら、index を返す
  4. Assert: module.[[Status]] は linked
  5. evaluatingmodule.[[Status]] にセットする
  6. indexmodule.[[DFSIndex]] にセットする
  7. indexmodule.[[DFSAncestorIndex]] にセットする
  8. index + 1index にセットする
  9. stackmodule を追加する
  10. module.[[RequestedModules]] の 各String要素を required とし、required ごとに次を実行する
    1. ! HostResolveImportedModule(module, required) を requiredModule とする
    2. NOTE: このメソッドを呼び出す前に Link が正常に完了する必要がある。そのため要求されたすべてのモジュールが正常に解決されることが保証される。
    3. ? InnerModuleEvaluation(requiredModule, stack, index) を index にセットする
    4. requiredModuleCyclicモジュールレコード なら、
      1. Assert: requiredModule.[[Status]] は evaluating または evaluated
      2. Assert: requiredModulestack にあるなら、requiredModule.[[Status]] は evaluating
      3. requiredModule.[[Status]] が evaluating なら、
        1. min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]) を module.[[DFSAncestorIndex]] にセットする
  11. ? module. ExecuteModule() を実行する
  12. Assert: modulestack で1回のみ発生
  13. Assert: module.[[DFSAncestorIndex]] は module[[DFSIndex]] 以下
  14. module.[[DFSAncestorIndex]] イコール module.[[DFSIndex]] なら
    1. falsedone とする
    2. donefalse の間繰り返し
      1. stack の最後の要素を requiredModule とする
      2. stack の最後の要素を削除する
      3. Assert: requiredModuleCyclicモジュールレコード
      4. evaluatedrequiredModule.[[Status]] にセットする
      5. requiredModulemodule が同じ モジュールレコード なら truedone にセット
  15. index を返す
15.2.1.16.3 Cyclicモジュールレコードグラフの例(Example Cyclic Module Record Graphs)

このセクションは非規範的です。ここではエラーがどのように発生するかに特に焦点を当てて、いくつかの一般的なモジュールグラフのリンクと評価の一連の例を示します。

まず、次の単純なモジュールグラフについて考えます。

簡単なモジュールグラフ
簡単なモジュールグラフ

エラー状態がないと仮定します。 ホストが最初にA.Link()を呼び出し正常に完了したとき、A.[[Status]] = B.[[Status]] = C.[[Status]] = linked のようにモジュールBCが再帰的にリンクします。この準備ステップはいつでも実行できます。 後で、ホストがモジュールの副作用をおこす準備ができたら、A.Evaluate()を呼び出して、最初のCとBを再帰的に評価して、正常に完了します。各モジュールの[[Status]]は、この時点でevaluated になります。

次に、リンクエラーを伴うケースを考えてみます。 CInnerModuleLinkingは成功したが、その後Bで失敗した場合(例:Cが提供しないものをインポートした)、元のA.Link()は失敗し、ABの[[Status]]は unlinked のままになります。 ただし、Cの[[ステータス]]は linked です。

最後に、評価エラーを伴うケースを考えてみます。 CInnerModuleEvaluationが成功したが、その後Bが失敗した場合(例:Bに例外をスローするコードが含まれている)、元のA.Evaluate()は失敗します。 結果として生じる例外は、ABの両方の[[EvaluationError]]フィールドに記録され、それらの[[Status]]が evaluated になります。 C もspan class="black b">evaluated になりますが、AおよびBとは対照的に、評価が正常に完了したため、[[EvaluationError]]はありません。 例外を保存することで、ホストがEvaluate()メソッドを呼び出してAまたはBを再利用しようとするたびに、同じ例外が発生することが保証されます。 (ホストはCyclicモジュールレコードを再利用する必要はありません。同様に、ホストはこれらのメソッドによってスローされた例外オブジェクトを公開する必要はありません。ただし、仕様ではそのような使用が可能です。)

リンクエラーと評価エラーが異なるのは、評価の実行は副作用を引き起こす可能性があるため、1回のみにする必要があるからです。 したがって、失敗した場合でも、評価がすでに実行されているかどうかを覚えておくことが重要です。 (エラーの場合、例外を覚えておくことも意味があります。そうしないと、後続のEvaluate()呼び出しで再度副作用を引き起こすためです。)一方、リンクは副作用がありません。問題なく再試行できます。

次に、別のタイプのエラー状態について考えます。

解決できないモジュールを含むモジュールグラフ
解決できないモジュールを含むモジュールグラフ

これは、モジュールAが他のモジュールへの依存関係を宣言しているが、そのモジュールのモジュールレコードが存在しないケースです。つまり、HostResolveImportedModuleが、要求されると例外がスローされます。 これは、対応するリソースが存在しない、またはリソースが存在するが、結果のソーステキストを解析しようとしたときにParseModuleが例外をスローするなど、さまざまな理由で発生します。 ホストは、HostResolveImportedModuleからスローする例外を介して、失敗の原因を明らかにすることを選択できます。 いずれの場合も、この例外によりリンク障害が発生し、以前と同様にAの[[ステータス]]は unlinked のままになります。

最後に、サイクルのあるモジュールグラフについて考えます。

cyclicモジュールグラフ

ここでは、エントリポイントがモジュールAであると想定しています。ホストはA.Link()を呼び出して続行します。A.Link()はAInnerModuleLinkingを実行します。これにより、BでもInnerModuleLinkingが呼び出されます。サイクルのため、AInnerModuleLinkingが再度トリガーされます。 しかし、A.[[Status]]はすでに linking のため、この時点では何も実行されません。 B.[[Status]]自体は、制御がAに戻り、CInnerModuleLinkingがトリガーされたときに linking を維持します。c.[[Status]]が linked で戻った後、ABの両方がlinking から linked に移行します。 これらは強く接続されたコンポーネントを形成するための仕様です。

成功した場合、Cyclicモジュールグラフの評価フェーズでも同様の現象が起こります。

ここで、Aにリンクエラーがある場合を考えてみます。 たとえば、存在しないCからバインディングをインポートしたケースです。 この場合、AInnerModuleLinkingへの2回目の呼び出しからの早期復帰を含め、上記の手順は引き続き発生します。ただし、Aの元のInnerModuleLinkingに戻ると、InitializeEnvironment中、つまりC.ResolveExport()の直後に失敗します。 スローされたSyntaxError例外は、A.Linkまで伝播します。これにより、現在stack上にあるすべてのモジュールがリセットされます(これらは、常にlinkingのモジュールと同じです)。 したがって、ABの両方が unlinked になります。 Clinkedのままであることに注意してください。

最後に、Aに評価エラーがある場合を考えます。 たとえば、ソースコードが例外をスローしたケースです。 この場合、上記のステップの評価時間アナログは、2 回目の呼び出しにおけるAInnerModuleEvaluationへの早期復帰を含め、依然として発生します。ただし、Aで元のInnerModuleEvaluationに戻ると、失敗します。 スローされた例外はA.Evaluate()まで伝播します。これは、現在stack上にあるすべてのモジュール(つまり、evaluatingのモジュール)のエラーを記録します。 したがって、ABの両方がevaluatedになり、例外がABの両方の[[EvaluationError]]フィールドに記録されます。Cは[[EvaluationError]]なしでevaluatedのままになります。

15.2.1.17 ソーステキストモジュールレコード(Source Text Module Records)

ソーステキストモジュールレコード

ソーステキストモジュールレコードは、ゴールシンボルModuleを使用して解析されたECMAScriptソーステキスト(10)で定義されたモジュールに関する情報を保持するために使用されます。 フィールドには、モジュールによってインポートされた名前に関するダイジェスト情報が含まれます。また、具象メソッドは、モジュールをリンク、リンク、および評価するためにダイジェスト情報を使用します。

ソーステキストモジュールレコードは、抽象モジュールレコード 型の他のサブクラスとともにモジュールグラフに存在できます。また、Cyclicモジュールレコード 型の他のサブクラスとともにサイクルに参加できます。

ソーステキストモジュールレコードは、表40に加えて、表42の追加フィールドを持ちます。これらの各フィールドは、最初はParseModuleで設定されます。

表42: ソーステキストモジュールレコードの追加フィールド
フィールド名 値の型 意味
[[ECMAScriptCode]] パースノード Moduleゴールシンボル として使用して、このモジュールのソーステキストを解析した結果。
[[Context]] ECMAScript 実行コンテキスト このモジュールに関連付けられている実行コンテキスト
[[ImportMeta]] Object import.metaメタプロパティを介して公開されたオブジェクト。 ECMAScriptコードによってアクセスされるまではemptyです。
[[ImportEntries]] ImportEntryレコードリスト このモジュールのコードから派生したImportEntryレコードのリスト。
[[LocalExportEntries]] ExportEntryレコードリスト モジュール内で発生する宣言に対応する、このモジュールのコードから派生したExportEntryレコードのリスト。
[[IndirectExportEntries]] ExportEntryレコードリスト モジュール内で発生する再エクスポートされたインポート、または export * as namespace宣言からのエクスポートに対応するこのモジュールのコードから派生したExportEntryレコードのリスト。
[[StarExportEntries]] ExportEntryレコードリスト モジュール内で発生するexport *宣言に対応する、このモジュールのコードから派生したExportEntryレコードのリスト。 export * as namespace 宣言は含まれません。

ImportEntryレコード

ImportEntryレコードは、単一の宣言型インポートに関する情報を保持するレコードです。 各ImportEntryレコードには、表43で定義されているフィールドがあります。

表43: ImportEntryレコードのフィールド
フィールド名 値の型 意味
[[ModuleRequest]] String ImportDeclarationModuleSpecifier のString値
[[ImportName]] String [[ModuleRequest]]で識別されるモジュールによってエクスポートされるバインディングの名前。 値 "*" は、インポート要求がターゲットモジュールの名前空間オブジェクトに対するものであることを示します。
[[LocalName]] String インポートモジュール内からインポートされた値を、ローカルからアクセスするために使用される名前。

表44に、Import構文で使用されるImportEntryレコードフィールドの例を示します。

表44: (参考)ImportEntryレコードのImport形式マッピング
Import文形式 [[ModuleRequest]] [[ImportName]] [[LocalName]]
import v from "mod"; "mod" "default" "v"
import * as ns from "mod"; "mod" "*" "ns"
import {x} from "mod"; "mod" "x" "x"
import {x} from "mod"; "mod" "x" "v"
import "mod"; ImportEntryレコードは作成されません。

ExportEntryレコード

ExportEntryレコードは、単一の宣言型エクスポートに関する情報を保持するレコードです。 各ExportEntryレコードには、表45で定義されているフィールドがあります。

表45: ExportEntryレコードのフィールド
フィールド名 値の型 意味
[[ExportName]] String |
null
バインディングをエクスポートするために使用される名前。
[[ModuleRequest]] String |
null
ExportDeclarationModuleSpecifierの文字列値。
ExportDeclarationModuleSpecifierがない場合はnull
[[ImportName]] String |
null
[[ModuleRequest]]で識別されるモジュールによって目的のバインディングがエクスポートされる名前。
ExportDeclarationModuleSpecifierがない場合はnull
"*" は、エクスポート要求がすべてのエクスポートされたバインディングに対するものであることを示します。
[[LocalName]] String |
null
インポートモジュールがエクスポートした値にローカルからアクセスするために使用される名前。
エクスポートされた値がモジュール内からローカルにアクセスできない場合はnull

表46に、Export構文で使用されるExportEntryレコードフィールドの例を示します。

表46: (参考)ExportEntryレコードのExport形式マッピング
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" "*" null
export * as
ns from "mod";
"ns" "mod" "*" null

以降の定義は、ソーステキストモジュールレコードの具象メソッドとその他の抽象操作を指定します。

15.2.1.17.1 ParseModule ( sourceText, realm, hostDefined )

引数sourceText, realm, hostDefinedを指定した抽象操作ParseModuleは、sourceTextModuleとして解析した結果に基づいてソーステキストモジュールレコードを作成します。 ParseModuleは、次の手順を実行します。

  1. Assert: sourceTextECMAScriptソーステキスト
  2. Moduleゴールシンボル として使用してsourceTextを解析します。 解析が成功し、早期エラーが見つからなかった場合は、結果の解析ツリーをbodyとします。 それ以外の場合は、解析エラーや早期エラーを表す1つ以上のSyntaxErrorオブジェクトのリストをbodyとします。 解析と早期エラーは、実装に依存する方法で検出される場合があります。 複数の解析エラーまたは早期エラーが存在する場合、リスト内のエラーオブジェクトの数と順序は実装に依存します。
  3. body が エラーのList なら body を返す
  4. bodyModuleRequestsrequestedModules とする
  5. bodyImportEntriesimportEntries とする
  6. ImportedLocalNames(importEntries) を importedBoundNames とする
  7. 空の新規ListindirectExportEntries とする
  8. 空の新規ListlocalExportEntries とする
  9. 空の新規ListstarExportEntries とする
  10. bodyExportEntriesexportEntries とする
  11. exportEntries の 各 ExportEntryレコード 要素を ee とし、 ee ごとに次を実行する
    1. ee.[[ModuleRequest]] が null なら、
      1. ee.[[LocalName]] が importedBoundNames の要素でないなら、
        1. localExportEntriesee を追加する
      2. i. と異なるなら、
        1. [[LocalName]] が ee.[[LocalName]] と同じ importEntries の要素を ie とする
        2. ie.[[ImportName]] が "*" なら、
          1. NOTE: これは、インポートされたモジュール名前空間オブジェクトの再エクスポート
          2. localExportEntriesee を追加する
        3. 2. と異なるなら、
          1. NOTE: これは単一名の再エクスポートです
          2. indirectExportEntriesExportEntryレコード { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } を追加する
    2. a. と異なり、 if ee.[[ImportName]] が "*"ee.[[ExportName]] が null なら、
      1. starExportEntriesee を追加する
    3. b. と異なるなら、
      1. indirectExportEntriesee を追加する
  12. ソーステキストモジュールレコード { [[Realm]]: realm, [[Environment]]: undefined, [[Namespace]]: undefined, [[Status]]: unlinked, [[EvaluationError]]: undefined, [[HostDefined]]: hostDefined, [[ECMAScriptCode]]: body, [[Context]]: empty, [[ImportMeta]]: empty, [[RequestedModules]]: requestedModules, [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries, [[IndirectExportEntries]]: indirectExportEntries, [[StarExportEntries]]: starExportEntries, [[DFSIndex]]: undefined, [[DFSAncestorIndex]]: undefined } を返す
実装は、モジュールのソーステキストを解析し、そのソーステキストのParseModuleを評価する前に、早期エラー状態を分析する場合があります。 ただし、エラー報告は、この仕様がそのソーステキストに対して実際にParseModuleを実行する時点まで延期する必要があります。
15.2.1.17.2 GetExportedNames ( [ exportStarSet ] ) 具象メソッド(Concrete Method)

ソーステキストモジュールレコードのGetExportedNames具象メソッドは、対応するモジュールレコード抽象メソッドを実装します。

  1. exportStarSet が 存在しないなら、 空の新規ListexportStarSet にセットする
  2. Assert: exportStarSetソーステキストモジュールレコード のリスト
  3. ソーステキストモジュールレコードmodule とする
  4. exportStarSetmodule が含まれるなら、
    1. Assert: export * サイクルの開始点に到達した
    2. 空の新規List を返す
  5. exportStarSetmodule を追加する
  6. 空の新規ListexportedNames とする
  7. module.[[LocalExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
    1. Assert: moduleは、このエクスポートの直接バインディングを提供する
    2. exportedNamese.[[ExportName]] を追加する
  8. module.[[IndirectExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
    1. Assert: module は、このエクスポートの特定のバインディングをインポートする
    2. exportedNamese.[[ExportName]] を追加する
  9. module.[[StarExportEntries]] の各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
    1. ? HostResolveImportedModule(module, e.[[ModuleRequest]]) を requestedModule とする
    2. ? requestedModule.GetExportedNames(exportStarSet) を starNames とする
    3. starNames の 各要素を n とし、n ごとに次を実行する
      1. SameValue(n, "default") が false なら、
        1. nexportedNames の要素でないなら、
          1. exportedNamesn を追加する
  10. exportedNames を返す
GetExportedNamesは、スターのエクスポートバインディングがあいまいな名前を除外したり、例外をスローしたりしません。
15.2.1.17.3 ResolveExport ( exportName [ , resolveSet ] ) 具象メソッド(Concrete Method)

ソーステキストモジュールレコードのResolveExport具象メソッドは、対応するモジュールレコード抽象メソッドを実装します。

ResolveExportは、インポートされたバインディングを実際の定義モジュールとローカルバインディング名で解決します。 定義モジュールは、このメソッドが呼び出されたモジュールレコード、またはモジュールによってインポートされた他のモジュールです。 パラメータresolveSetは、未解決の循環インポート/エクスポートパスを検出するために使用されます。 特定のモジュールレコードとexportNameがすでにresolveSetにセットされている場合、インポートの循環が発生しています。 ResolveExportを再帰的に呼び出す前に、moduleexportNameで構成されるペアがresolveSetに追加されます。

定義モジュールがある場合、ResolvedBindingレコード {[[Module]],[[BindingName]]}が返されます。 このレコードが、ローカルバインディングを持たない名前空間のエクスポートでない限り、最初に要求されたエクスポートの解決されたバインディングを識別します。 この場合、[[BindingName]]は "*namespace*" に設定されます。 定義がない場合、またはリクエストが循環している場合は、nullが返されます。 要求があいまいであることが判明した場合、文字列 "ambiguous" が返されます。

この抽象メソッドは、次の手順を実行します。

  1. resolveSet が存在しないなら、 空の新規ListresolveSet にセットする
  2. Assert: resolveSetRecord { [[Module]], [[ExportName]] } のリスト
  3. ソーステキストモジュールレコードmodule とする
  4. resolveSet の 各 Record { [[Module]], [[ExportName]] } 要素を r とし、 r ごとに次を実行する
    1. moduler.[[Module]] が 同じ モジュールレコードSameValue(exportName, r.[[ExportName]]) が true なら、
      1. Assert: これは循環インポートリクエスト
      2. null を返す
  5. resolveSetRecord { [[Module]]: module, [[ExportName]]: exportName } を追加する
  6. module.[[LocalExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
    1. SameValue(exportName, e.[[ExportName]]) が true なら、
      1. Assert:module は、このエクスポートの直接バインディングを提供する
      2. ResolvedBindingレコード { [[Module]]: module, [[BindingName]]: e.[[LocalName]] } を返す
  7. module.[[IndirectExportEntries]] の各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
    1. SameValue(exportName, e.[[ExportName]]) が true なら、
      1. ? HostResolveImportedModule(module, e.[[ModuleRequest]]) を importedModule とする
      2. e.[[ImportName]] が "*" なら、
        1. Assert: moduleは、このエクスポートの直接バインディングを提供しない
        2. ResolvedBindingレコード { [[Module]]: importedModule, [[BindingName]]: "*namespace*" } を返す
      3. ii. と異なるなら、
        1. Assert: moduleは、このエクスポートの特定のバインディングをインポートする
        2. importedModule.ResolveExport(e.[[ImportName]], resolveSet) を返す
  8. SameValue(exportName, "default") が true なら、
    1. Assert: デフォルトのエクスポートが、このモジュールによって明示的に定義されていない
    2. null を返す
    3. NOTE: デフォルトのエクスポートは、export * または export * from "mod" 宣言では提供できない
  9. nullstarResolution とする
  10. module.[[StarExportEntries]] の 各 ExportEntryレコード 要素を e とし、 ExportEntryレコード e ごとに次を実行する
    1. ? HostResolveImportedModule(module, e.[[ModuleRequest]]) を importedModule とする
    2. ? importedModule.ResolveExport(exportName, resolveSet) を resolution とする
    3. resolution"ambiguous" なら "ambiguous" を返す
    4. resolutionnull でないなら、
      1. Assert: resolutionResolvedBindingレコード
      2. starResolutionnull なら、 resolutionstarResolution にセットする
      3. ii. と異なるなら、
        1. Assert: 要求された名前を含む*インポートが複数ある
        2. resolution.[[Module]] と starResolution.[[Module]] が同じ モジュールレコード ではないか、 SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) が false なら "ambiguous" を返す
  11. starResolution を返す
15.2.1.17.4 InitializeEnvironment ( ) 具象メソッド(Concrete Method)

ソーステキストモジュールレコード のInitializeEnvironment具象メソッドは、対応するCyclicモジュールレコード の抽象メソッドを実装します。

この抽象メソッドは、次の手順を実行します。

  1. this ソーステキストモジュールレコードmodule とする
  2. module.[[IndirectExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
    1. ? module.ResolveExport(e.[[ExportName]]) を resolution とする
    2. resolutionnull または "ambiguous" なら SyntaxError例外をスローする
    3. Assert: resolutionResolvedBindingレコード
  3. Assert: moduleからのすべての名前付きエクスポートが解決可能
  4. module.[[Realm]] を realm とする
  5. Assert: realmundefined ではない
  6. NewModuleEnvironment(realm.[[GlobalEnv]]) を env とする
  7. envmodule.[[Environment]] にセットする
  8. envEnvironmentRecordenvRec とする
  9. module.[[ImportEntries]] の 各 ImportEntryレコード 要素を in とし、 in ごとに次を実行する
    1. ! HostResolveImportedModule(module, in.[[ModuleRequest]]) を importedModule とする
    2. NOTE: インポートされたモジュール要求はmodule.[[RequestedModules]]のサブセットであり、これらはこのアルゴリズムの初期の段階で解決されているため、上記の呼び出しは失敗しない
    3. in.[[ImportName]] が "*" なら、
      1. ? GetModuleNamespace(importedModule) を namespace とする
      2. ! envRec. CreateImmutableBinding(in.[[LocalName]], true) を実行する
      3. envRec.InitializeBinding(in.[[LocalName]], namespace) をコール
    4. c. と異なるなら、
      1. ? importedModule.ResolveExport(in.[[ImportName]]) を resolution とする
      2. resolutionnull または "ambiguous" なら SyntaxError例外をスローする
      3. resolution.[[BindingName]] が "*namespace*" なら、
        1. ? GetModuleNamespace(resolution.[[Module]]) を namespace とする
        2. ! envRec. CreateImmutableBinding(in.[[LocalName]], true) を実行する
        3. envRec.InitializeBinding(in.[[LocalName]], namespace) をコール
      4. iii. と異なるなら、
        1. envRec.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]) をコール
  10. 新規 ECMAScriptコード実行コンテキストmoduleContext とする
  11. nullmoduleContextFunctionコンポーネント にセットする
  12. Assert: module.[[Realm]] は undefined ではない
  13. modulemoduleContextRealmコンポーネント にセットする [[Realm]]
  14. modulemoduleContextScriptOrModuleコンポーネント にセットする
  15. modulemoduleContextVariableEnvironmentコンポーネント にセットする [[Environment]]
  16. modulemoduleContextLexicalEnvironmentコンポーネント にセットする [[Environment]]
  17. moduleContextmodule.[[Context]] にセットする
  18. moduleContext実行コンテキストスタックにプッシュする。moduleContext実行中の実行コンテキストになる
  19. module.[[ECMAScriptCode]] を code とする
  20. codeVarScopedDeclarationsvarDeclarations とする
  21. 空の新規ListdeclaredVarNames とする
  22. varDeclarations の 各要素を d とし、d ごとに次を実行する
    1. dBoundNames の各要素を dn とし、dn ごとに次を実行する
      1. dndeclaredVarNames の要素でないなら、
        1. ! envRec.CreateMutableBinding(dn, false) を実行する
        2. envRec. InitializeBinding(dn, undefined) をコール
        3. declaredVarNamesdn を追加する
  23. codeLexicallyScopedDeclarationslexDeclarations とする
  24. lexDeclarations の 各要素を d とし、d ごとに次を実行する
    1. dBoundNames の 各要素を dn とし、dn ごとに次を実行する
      1. dIsConstantDeclarationtrue なら、
        1. ! envRec. CreateImmutableBinding(dn, true) を実行する
      2. i. と異なるなら、
        1. ! envRec. CreateMutableBinding(dn, false) を実行する
      3. dFunctionDeclaration または GeneratorDeclaration または AsyncFunctionDeclaration または AsyncGeneratorDeclaration なら、
        1. 引数 env を使用して dInstantiateFunctionObjectfo とする
        2. envRec.InitializeBinding(dn, fo) をコールする
  25. 実行コンテキストスタック から moduleContext を削除する
  26. NormalCompletion(empty) を返す
15.2.1.17.5 ExecuteModule ( ) 具象メソッド(Concrete Method)

ソーステキストモジュールレコードのExecuteModule具象メソッドは、対応するCyclicモジュールレコード 抽象メソッドを実装します。

この抽象メソッドは、次の手順を実行します。

  1. ソーステキストモジュールレコードmodule とする
  2. 現在の実行中の実行コンテキストSuspendする
  3. module.[[Context]] を moduleContext とする
  4. moduleContext実行コンテキストスタック にプッシュする。moduleContext実行中の実行コンテキスト になる
  5. module.[[ECMAScriptCode]] の評価結果を result とする
  6. moduleContextSuspend し、実行コンテキストスタックから削除する
  7. 実行コンテキストスタック の最上位にあるコンテキストを 実行中の実行コンテキスト として再開する
  8. Completion(result) を返す

15.2.1.18 ランタイムセマンティクス(Runtime Semantics): HostResolveImportedModule ( referencingScriptOrModule, specifier )

HostResolveImportedModuleは、スクリプトレコードまたはモジュールレコードreferencingScriptOrModule にに対応するスクリプトまたはモジュールのコンテキスト内で発生するModuleSpecifier String、specifierに対応する具体的なモジュールレコードサブクラスインスタンスを提供する実装定義の抽象操作です。 import() 式のコンテキストで解決が実行されており、その時点でアクティブなスクリプトまたはモジュールがない場合、referencingScriptOrModulenullになる可能性があります。

referenceScriptOrModulenullになる可能性がある場合の例:

Webブラウザーホストで、次のようなコントロールをクリックすると、

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

import() 式の実行時には、アクティブなスクリプトまたはモジュールはありません。 より一般的には、これは、ホストがnullのScriptOrModuleコンポーネントを含む実行コンテキストを実行コンテキストスタックにプッシュする状況で発生する可能性があります。

HostResolveImportedModuleの実装は、次の要件に準拠する必要があります。

  • 通常の戻り値は、モジュールレコード の具象サブクラスのインスタンスである必要があります。
  • ScriptOrModulespecifier に対応するモジュールレコードが存在しないか、作成できない場合は、例外をスローする必要があります。
  • 同じ referencingScriptOrModulespecifierのペアが引数として呼び出されたら、同じモジュールレコードインスタンスを返す必要があります。(正常に完了した場合)

複数の異なるreferenceingScriptOrModulespecifierのペアは、同じモジュールレコードインスタンスにマップされる場合があります。 実際のマッピングセマンティクスは実装によって定義されますが、通常、正規化プロセスはマッピングプロセスの一部としてspecifierに適用されます。 典型的な正規化プロセスには、アルファベットの大文字小文字の区別や、相対パス指定子と省略パス指定子の展開などのアクションが含まれます。

15.2.1.19 ランタイムセマンティクス(Runtime Semantics): HostImportModuleDynamically ( referencingScriptOrModule, specifier, promiseCapability )

referenceingScriptOrModuleは、スクリプトレコードまたはモジュールレコードです。specifierは、referenceingScriptOrModuleに対応するスクリプトまたはモジュールのコンテキスト内で発生するModuleSpecifierの文字列です。HostImportModuleDynamicallyは実装定義の抽象操作で、specifierに対応するモジュールを使用可能にするために必要なセットアップ作業を実行します。(import()式が発生したときにアクティブなスクリプトまたはモジュールがない場合、referencingScriptOrModulenullになる可能性があります。)次に、FinishDynamicImportを実行して、動的インポートプロセスを終了します。

HostImportModuleDynamicallyの実装は、次の要件に準拠する必要があります。

  • 抽象操作は、常にundefinedで正常に完了する必要があります。 代わりに、以下で説明するように、成功または失敗を通知する必要があります
  • ホスト環境は、次の2つの要件セットのいずれかに準拠している必要があります。

    成功時:

    • 将来的には、ホスト環境で次を実行する必要があります

      FinishDynamicImport(referencingScriptOrModule, specifier, promiseCapability, NormalCompletion(undefined))

    • 引数referencingScriptOrModulespecifierを指定して、FinishDynamicImportが完了した後のHostResolveImportedModuleへの後続の呼び出しは、正常に完了する必要があります。
    • 引数referencingScriptOrModulespecifierを指定して、FinishDynamicImportが完了した後のHostResolveImportedModuleへの後続呼び出しの完了値は、評価済モジュールである必要があります。つまり、Evaluate具象メソッドがすでに呼び出され、通常の完了を返している必要があります。

    失敗時:

    • 将来的には、ホスト環境でFinishDynamicImport(referencingScriptOrModule, specifier, promiseCapability突然の完了) を実行する必要があります。突然の完了は失敗の原因を表します。
  • ホスト環境が特定のreferencingScriptOrModulespecifierペアに対して一度成功した場合、再呼び出しでも成功する必要があります。
  • 操作は、promiseCapability.[[Resolve]]またはpromiseCapability.[[Reject]]を呼び出さないでください。代わりに、promiseCapabilityFinishDynamicImportに渡される不透明な識別値として扱う必要があります。

実際のプロセスは実装によって定義されます。通常、HostResolveImportedModuleが適切なモジュールコードを同期的に取得するために必要なI/O操作を実行し、Evaluate具象メソッドを呼び出すことで構成されます。 これには、HostResolveImportedModuleと同様の正規化が必要な場合があります。

15.2.1.20 ランタイムセマンティクス(Runtime Semantics): FinishDynamicImport ( referencingScriptOrModule, specifier, promiseCapability, completion )

FinishDynamicImportは、元々import() 呼び出しによって開始された動的インポートのプロセスを完了し、completionに従って、その呼び出しが返したプロミスを解決または拒否します。 これは、HostImportModuleDynamicallyの一部としてホスト環境によって実行されます。

  1. completion突然の完了 なら、 ! Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] ») を実行する
  2. 1. と異なるなら、
    1. Assert: completion は正常完了で、 completion[[Value]] は undefined
    2. ! HostResolveImportedModule(referencingScriptOrModule, specifier) を moduleRecord とする
    3. Assert: EvaluateはmoduleRecordで呼び出し済みで、正常に完了している
    4. GetModuleNamespace(moduleRecord) を namespace とする
    5. namespace突然の完了 なら、 ! Call(promiseCapability.[[Reject]], undefined, « namespace.[[Value]] ») を実行する
    6. e. と異なるなら、 ! Call(promiseCapability.[[Resolve]], undefined, « namespace.[[Value]] ») を実行する

15.2.1.21 ランタイムセマンティクス(Runtime Semantics): GetModuleNamespace ( module )

GetModuleNamespace抽象操作は、moduleのエクスポートを表すモジュール名前空間オブジェクトを取得します。ただし、初回要求時は遅延作成し、将来の取得のためにmodule.[[Namespace]]に格納します。

この抽象操作は、次の手順を実行します。

  1. Assert: moduleモジュールレコード の具象サブクラスのインスタンス
  2. Assert: moduleCyclicモジュールレコード なら、 module[[Status]] は unlinked ではない
  3. module.[[Namespace]] を namespace とする
  4. namespaceundefined なら、
    1. ? module.GetExportedNames() を exportedNames とする
    2. 空の新規ListunambiguousNames とする
    3. exportedNames の各要素を name とし、name ごとに次を実行する
      1. ? module.ResolveExport(name) を resolution とする
      2. resolutionResolvedBindingレコード なら、unambiguousNamesname を追加する
    4. ModuleNamespaceCreate(module, unambiguousNames) を namespace にセットする
  5. namespace を返す
GetModuleNamespaceがスローできる唯一の方法は、トリガーされたHostResolveImportedModule呼び出しの1つを使用することです。 解決できない名前は、この時点で名前空間から単純に除外されます。 それらがすべてどこにも明示的に要求されていないあいまいなスターエクスポートでない限り、後で実際のリンクエラーが発生します。

15.2.1.22 ランタイムセマンティクス:評価(Runtime Semantics: Evaluation)

  1. NormalCompletion(undefined) を返す
  1. ModuleItemList の評価結果を result とする
  2. result.[[Type]] が normal and result.[[Value]] is empty なら、
    1. NormalCompletion(undefined) を返す
  3. Completion(result) を返す
  1. ModuleItemList の評価結果を sl とする
  2. ReturnIfAbrupt(sl)
  3. ModuleItem の評価結果を s とする
  4. Completion( UpdateEmpty(s, sl)) を返す
ModuleItemListの値は、ModuleItemList内の最後の値を生成するアイテムの値です。
  1. NormalCompletion(empty) を返す

15.2.2 Imports

構文:

15.2.2.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)

  • ImportDeclarationBoundNames に重複する要素が含まれているなら、構文エラー

15.2.2.2 静的セマンティクス(Static Semantics): BoundNames

  1. ImportClauseBoundNames を返す
  1. 空の新規List を返す
  1. ImportedDefaultBindingBoundNamesnames とする
  2. NameSpaceImportBoundNames の要素を names に追加する
  3. names を返す
  1. ImportedDefaultBindingBoundNamesnames とする
  2. NamedImportsBoundNames の要素を names に追加する
  3. names を返す
  1. 空の新規List を返す
  1. ImportsListBoundNamesnames とする
  2. ImportSpecifierBoundNames の要素を names に追加する
  3. names を返す
  1. ImportedBindingBoundNames を返す

15.2.2.3 静的セマンティクス(Static Semantics): ImportEntries

  1. FromClauseModuleRequests の唯一の要素を module とする
  2. 引数 module を使用して ImportClauseImportEntriesForModule の実行結果を返す
  1. 空の新規List を返す

15.2.2.4 静的セマンティクス(Static Semantics): ImportEntriesForModule

引数 module を使用。

  1. 引数 module を使用して ImportedDefaultBindingImportEntriesForModuleentries とする
  2. 引数 module を使用して NameSpaceImportImportEntriesForModule の要素を entries に追加する
  3. entries を返す
  1. 引数 module を使用して ImportedDefaultBindingImportEntriesForModuleentries とする
  2. 引数 module を使用して NamedImportsImportEntriesForModule の要素を entries に追加する
  3. entries を返す
  1. ImportedBindingBoundNames の唯一の要素を localName とする
  2. ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName } を defaultEntry とする
  3. defaultEntry を含む新規List を返す
  1. ImportedBindingStringValuelocalName とする
  2. ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: localName } を entry とする
  3. entry を含む新規List を返す
  1. 空の新規List を返す
  1. 引数 module を使用して ImportsListImportEntriesForModulespecs とする
  2. 引数 module を使用して ImportSpecifierImportEntriesForModule の要素を specs に追加する
  3. specs を返す
  1. ImportedBindingBoundNames の唯一の要素を localName とする
  2. ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName } を entry とする
  3. entry を含む新規List を返す
  1. IdentifierNameStringValueimportName とする
  2. ImportedBindingStringValuelocalName とする
  3. ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName } を entry とする
  4. entry を含む新規List を返す

15.2.2.5 静的セマンティクス(Static Semantics): ModuleRequests

  1. FromClauseModuleRequests を返す
  1. StringLiteralStringValue を含む Listを返す

15.2.3 Exports

構文:

ExportDeclaration :

exportNamedExports ;
exportVariableStatement[~Yield, ~Await]
exportDeclaration[~Yield, ~Await]
exportdefaultHoistableDeclaration[~Yield, ~Await, +Default]
exportdefaultClassDeclaration[~Yield, ~Await, +Default]
exportdefault[lookahead ∉ { function, async [no LineTerminator here] function, class }]AssignmentExpression[+In, ~Yield, ~Await] ;

15.2.3.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)

  • NamedExportsのReferencedBindingsの各IdentifierNamen とする。n の StringValue が ReservedWordであるか、"implements"、"interface"、"let"、"package"、"private"、"protected"、"public"、 "static" のどれかなら、構文エラー。
上記のルールは、NamedExportsの各ReferencedBindingsがIdentifierReferenceとして扱われることを意味します。

15.2.3.2 静的セマンティクス(Static Semantics): BoundNames

  1. 空の新規List を返す
  1. VariableStatementBoundNames を返す
  1. DeclarationBoundNames を返す
  1. HoistableDeclarationBoundNamesdeclarationNames とする
  2. declarationNames"*default*" が含まれていないなら、declarationNames"*default*" を追加する
  3. declarationNames を返す
  1. ClassDeclarationBoundNamesdeclarationNames とする
  2. declarationNames"*default*"が含まれていないなら、declarationNames"*default*" を追加する
  3. declarationNames を返す
  1. « "*default*" » を返す

15.2.3.3 静的セマンティクス(Static Semantics): ExportedBindings

  1. 空の新規List を返す
  1. NamedExportsExportedBindings を返す
  1. VariableStatementBoundNames を返す
  1. DeclarationBoundNames を返す
  1. ExportDeclarationBoundNames を返す
  1. 空の新規List を返す
  1. ExportsListExportedBindingsnames とする
  2. ExportSpecifierExportedBindings の要素を names に追加する
  3. names を返す
  1. IdentifierNameStringValue を含む Listを返す
  1. 最初の IdentifierNameStringValue を含む Listを返す

15.2.3.4 静的セマンティクス(Static Semantics): ExportedNames

  1. ExportFromClauseExportedNames を返す
  1. 空の新規List を返す
  1. IdentifierNameStringValue を含む Listを返す
  1. NamedExportsExportedNames を返す
  1. VariableStatementBoundNames を返す
  1. DeclarationBoundNames を返す
  1. « "default" » を返す
  1. 空の新規List を返す
  1. ExportsListExportedNamesnames とする
  2. ExportSpecifierExportedNames の要素を names に追加する
  3. names を返す
  1. IdentifierNameStringValue を含む Listを返す
  1. 2番目の IdentifierNameStringValue を含む Listを返す

15.2.3.5 静的セマンティクス(Static Semantics): ExportEntries

  1. FromClauseModuleRequests の唯一の要素を module とする
  2. 引数 module を使用して ExportFromClauseExportEntriesForModule の実行結果を返す
  1. 引数 null を使用して NamedExportsExportEntriesForModule の実行結果を返す
  1. 空の新規Listentries とする
  2. VariableStatementBoundNamesnames とする
  3. names の 各要素を name とし、name ごとに次を実行する
    1. entriesExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } を追加する
  4. entries を返す
  1. 空の新規Listentries とする
  2. DeclarationBoundNamesnames とする
  3. names の 各要素を name とし、name ごとに次を実行する
    1. entriesExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } を追加する
  4. entries を返す
  1. HoistableDeclarationBoundNamesnames とする
  2. names の唯一の要素を localName とする
  3. ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } を含む新しいリストを返す
  1. ClassDeclarationBoundNamesnames とする
  2. names の唯一の要素を localName とする
  3. ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } を含む新しいリストを返す
  1. ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: "*default*", [[ExportName]]: "default" } を entry とする
  2. entry を含む新規List を返す
"*default*" は、匿名のデフォルトエクスポート値の合成名としてこの仕様内で使用されます。

15.2.3.6 静的セマンティクス(Static Semantics): ExportEntriesForModule

引数 module を使用。

  1. ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: null, [[ExportName]]: null } を entry とする
  2. entry を含む新規List を返す
  1. IdentifierNameStringValueexportName とする
  2. ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: null, [[ExportName]]: exportName } を entry とする
  3. entry を含む新規List を返す
  1. 空の新規List を返す
  1. 引数 module を使用して ExportsListExportEntriesForModulespecs とする
  2. 引数 module を使用して ExportSpecifierExportEntriesForModule の要素を specs に追加する
  3. specs を返す
  1. IdentifierNameStringValuesourceName とする
  2. modulenull なら、
    1. sourceNamelocalName とする
    2. nullimportName とする
  3. 11. と異なるなら、
    1. nulllocalName とする
    2. sourceNameimportName とする
  4. ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: sourceName } を含む新しいリストを返す
  1. 最初の IdentifierNameStringValuesourceName とする
  2. 2番目の IdentifierNameStringValueexportName とする
  3. modulenull なら、
    1. sourceNamelocalName とする
    2. nullimportName とする
  4. undefined. と異なるなら、
    1. nulllocalName とする
    2. sourceNameimportName とする
  5. ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: exportName } を含む新しいリストを返す

15.2.3.7 静的セマンティクス(Static Semantics): IsConstantDeclaration

  1. false を返す
モジュールのデフォルトオブジェクトを参照する内部バインド名への割り当てを許可する構文がないため、export default AssignmentExpressionを定数宣言として扱う必要はありません。

15.2.3.8 静的セマンティクス(Static Semantics): LexicallyScopedDeclarations

  1. 空の新規List を返す
  1. DeclarationDeclarationPart を含む新しいリストを返す
  1. HoistableDeclarationDeclarationPart を含む新しいリストを返す
  1. ClassDeclaration を含む新しいリストを返す
  1. ExportDeclaration を含む新しいリストを返す

15.2.3.9 静的セマンティクス(Static Semantics): ModuleRequests

  1. FromClauseModuleRequests を返す
  1. 空の新規List を返す

15.2.3.10 静的セマンティクス(Static Semantics): ReferencedBindings

  1. 空の新規List を返す
  1. ExportsListReferencedBindingsnames とする
  2. ExportSpecifierReferencedBindings の要素を names に追加する
  3. names を返す
  1. IdentifierName を含むリストを返す
  1. 最初の IdentifierName を含むリストを返す

15.2.3.11 ランタイムセマンティクス:評価(Runtime Semantics: Evaluation)

  1. NormalCompletion(empty) を返す
  1. VariableStatement の 評価結果を返す
  1. Declaration の 評価結果を返す
  1. HoistableDeclaration の 評価結果を返す
  1. ClassDeclaration? BindingClassDeclarationEvaluationvalue とする
  2. ClassDeclarationBoundNames の唯一の要素を className とする
  3. className"*default*" なら、
    1. 実行中の実行コンテキスト の LexicalEnvironment を env とする
    2. ? InitializeBoundName("*default*", value, env) を実行する
  4. NormalCompletion(empty) を返す
  1. IsAnonymousFunctionDefinition(AssignmentExpression ) が true なら、
    1. 引数 "default" を使用して AssignmentExpressionNamedEvaluationvalue とする
  2. 9. と異なるなら、
    1. AssignmentExpression の評価結果を rhs とする
    2. ? GetValue(rhs) を value とする
  3. 実行中の実行コンテキスト の LexicalEnvironment を env とする
  4. ? InitializeBoundName("*default*", value, env) を実行する
  5. NormalCompletion(empty) を返す