15.1 スクリプト(Scripts)
構文:
Script :
15.1.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)
- ScriptBody の LexicallyDeclaredNames に重複する要素が含まれているなら、構文エラー
- ScriptBody の LexicallyDeclaredNames のいずれかの要素が、 ScriptBody の VarDeclaredNames にもあるなら、構文エラー
- superを含むソースコードが、ダイレクトeval によって処理されているevalコードでないとき、StatementList に super が含まれている場合は構文エラーです。 ダイレクトeval内の super の追加の早期エラールールは、18.2.1.1で定義されています。
- NewTarget を含むソースコードが ダイレクトeval によって処理されているevalコードでないとき、StatementList に NewTarget が含まれていると、構文エラーです。 ダイレクトeval における NewTargetの追加の早期エラールールは18.2.1.1で定義されています。
- 引数 « » を使用して StatementList の ContainsDuplicateLabels が true なら、構文エラー
- 引数 « » を使用して StatementList の ContainsUndefinedBreakTarget が true なら、構文エラー
- 引数 « » と « » を使用して StatementList の ContainsUndefinedContinueTarget が true なら、構文エラー
15.1.2 静的セマンティクス(Static Semantics): IsStrict
Script :
- ScriptBody の ScriptBody が存在し、 ディレクティブプロローグ に Use Strictディレクティブ が含まれているなら true を、含まれていないなら false を返す
15.1.3 静的セマンティクス(Static Semantics): LexicallyDeclaredNames
- StatementList の TopLevelLexicallyDeclaredNames を返す
15.1.4 静的セマンティクス(Static Semantics): LexicallyScopedDeclarations
- StatementList の TopLevelLexicallyScopedDeclarations を返す
15.1.5 静的セマンティクス(Static Semantics): VarDeclaredNames
- StatementList の TopLevelVarDeclaredNames を返す
15.1.6 静的セマンティクス(Static Semantics): VarScopedDeclarations
- StatementList の TopLevelVarScopedDeclarations を返す
15.1.7 ランタイムセマンティクス:評価(Runtime Semantics: Evaluation)
- NormalCompletion(undefined) を返す
15.1.8 スクリプトレコード(Script Records)
スクリプトレコード
スクリプトレコードは、評価されるスクリプトに関する情報をカプセル化します。 各スクリプトレコードには、表37にリストされているフィールドが含まれています。
フィールド名 | 値の型 | 意味 |
---|---|---|
[[Realm]] | レルムレコード | undefined |
スクリプトを作成したレルム。 まだ割り当てられていない場合はundefined。 |
[[Environment]] | レキシカル環境 | undefined |
スクリプトの最上位のバインディングを含むレキシカル環境。 このフィールドは、スクリプトがインスタンス化されるときに設定されます。 |
[[ECMAScriptCode]] | パースノード | Scriptをゴールシンボルとして使用して、 このスクリプトのソーステキストを解析した結果。 |
[[HostDefined]] | 不特定 デフォルト値はundefined |
スクリプトに関連付ける追加情報。 ホスト環境で使用するために予約されている |
15.1.9 ParseScript ( sourceText, realm, hostDefined )
引数sourceText、 realm、 hostDefinedを使用した抽象操作ParseScriptは、sourceTextをScriptとして解析した結果に基づいてスクリプトレコードを作成します。 ParseScriptは、次の手順を実行します。
- Assert: sourceText は ECMAScriptソーステキスト
- Scriptをゴールシンボルとして使用してsourceTextを解析する。解析が成功し、早期エラーがないなら、結果の解析ツリーをbody をする。 それ以外なら、解析エラーや早期エラーを表す1つ以上のSyntaxErrorオブジェクトのリスト body をする。 解析と早期エラー検出は、実装に依存する方法する場合がある。 解析エラーまたは早期エラーが複数ある場合、リスト内のエラーオブジェクトの数と順序は実装に依存する。ただし、少なくとも1つは必要。
- body が エラーの List なら、 body を返す
- スクリプトレコード { [[Realm]]: realm, [[Environment]]: undefined, [[ECMAScriptCode]]: body, [[HostDefined]]: hostDefined } を返す
15.1.10 ScriptEvaluation ( scriptRecord )
- scriptRecord.[[Realm]].[[GlobalEnv]] を globalEnv とする
- 新規 ECMAScriptコード実行コンテキスト を scriptContext とする
- null を scriptContext の Functionコンポーネント にセットする
- scriptRecord を scriptContext の Realmコンポーネント にセットする [[Realm]]
- scriptRecord を scriptContext の ScriptOrModuleコンポーネント にセットする
- globalEnv を scriptContext の VariableEnvironmentコンポーネント にセットする
- globalEnv を scriptContext の LexicalEnvironmentコンポーネント にセットする
- 現在の実行中の実行コンテキストをSuspendする
- scriptContext を実行コンテキストスタックにプッシュする。scriptContextが実行中の実行コンテキストになる
- scriptRecord.[[ECMAScriptCode]] を scriptBody とする
- GlobalDeclarationInstantiation(scriptBody, globalEnv) を result とする
- result.[[Type]] が normal なら、
- scriptBody の評価結果を result にセットする
- result.[[Type]] が normal で result.[[Value]] is empty なら、
- NormalCompletion(undefined) を result にセットする
- scriptContext を Suspend し、実行コンテキストスタックから削除する
- Assert: 実行コンテキストスタック は empty ではない
- 実行コンテキストスタックの最上位にあるコンテキストを実行中の実行コンテキストとして再開する
- Completion(result) を返す
15.1.11 ランタイムセマンティクス(Runtime Semantics): GlobalDeclarationInstantiation ( script, env )
GlobalDeclarationInstantiationは、引数scriptとenvを使用して次のように実行されます。 scriptは、実行コンテキストが確立されているScriptBodyです。 envは、バインディングが作成されるグローバルなレキシカル環境です。
- env の EnvironmentRecord を envRec とする
- Assert: envRec は グローバル環境レコード
- script の LexicallyDeclaredNames を lexNames とする
- script の VarDeclaredNames を varNames とする
- lexNames の 各要素を name とし、name ごとに次を実行する
- envRec.HasVarDeclaration(name) が true なら、 SyntaxError例外をスローする
- envRec.HasLexicalDeclaration(name) が true なら、SyntaxError例外をスローする
- ? envRec.HasRestrictedGlobalProperty(name) を hasRestrictedGlobal とする
- hasRestrictedGlobal が true なら、 SyntaxError例外をスローする
- varNames の 各要素を name とし、name ごとに次を実行する
- envRec.HasLexicalDeclaration(name) が true なら、SyntaxError例外をスローする
- script の VarScopedDeclarations を varDeclarations とする
- 空の新規List を functionsToInitialize とする
- 空の新規List を declaredFunctionNames とする
- varDeclarations 内の各要素を d とし、リストの逆順で次を実行する
- d が VariableDeclaration、ForBinding、BindingIdentifier のどれでないなら、
- Assert: d は FunctionDeclaration、GeneratorDeclaration、AsyncFunctionDeclaration、AsyncGeneratorDeclaration のどれか
- NOTE: 同名の関数宣言は、最後の宣言が使用される
- d の BoundNames の唯一の要素を fn とする
- fn が declaredFunctionNames の要素でないなら、
- ? envRec.CanDeclareGlobalFunction(fn) を fnDefinable とする
- fnDefinable が false なら、 TypeError例外をスローする
- declaredFunctionNames に fn を追加する
- functionsToInitialize の最初に d を挿入する
- d が VariableDeclaration、ForBinding、BindingIdentifier のどれでないなら、
- 空の新規List を declaredVarNames とする
- varDeclarations の 各要素を d とし、d ごとに次を実行する
- d が VariableDeclaration か ForBinding か BindingIdentifier なら、
- d の BoundNames 内の文字列を vn とし、 vn ごとに次を実行する
- vn が declaredFunctionNames の要素でないなら、
- ? envRec.CanDeclareGlobalVar(vn) を vnDefinable とする
- vnDefinable が false なら、 TypeError例外をスローする
- vn が declaredVarNames の要素でないなら、
- declaredVarNames に vn を追加する
- vn が declaredFunctionNames の要素でないなら、
- d の BoundNames 内の文字列を vn とし、 vn ごとに次を実行する
- d が VariableDeclaration か ForBinding か BindingIdentifier なら、
- NOTE: グローバルオブジェクト が通常のオブジェクト である場合、このアルゴリズムステップの後に異常終了は発生しません。 ただし、グローバルオブジェクトがProxyエキゾチックオブジェクト である場合、以降手順の一部で異常終了が発生する可能性があります
- NOTE: 付録B.3.3.2に、追加の手順あり
- script の LexicallyScopedDeclarations を lexDeclarations とする
- lexDeclarations の 各要素を d とし、d ごとに次を実行する
- functionsToInitialize の 各要素を パースノード f とし、パースノード f ごとに次を実行する
- f の BoundNames の唯一の要素を fn とする
- 引数 env を使用して f の InstantiateFunctionObject を fo とする
- ? envRec.CreateGlobalFunctionBinding(fn, fo, false) を実行する
- declaredVarNames の 各文字列 を vn とし、各 vn をリスト順に次を実行する
- ? envRec.CreateGlobalVarBinding(vn, false) を実行する
- NormalCompletion(empty) を返す
15.2 モジュール(Modules)
構文:
Module :
15.2.1 モジュールセマンティクス(Module Semantics)
15.2.1.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)
- ModuleItemList の LexicallyDeclaredNames に重複する要素が含まれているなら、構文エラー
- ModuleItemList の LexicallyDeclaredNames のいずれかの要素が、 ModuleItemList の VarDeclaredNames にもあるなら、構文エラー
- ModuleItemList の ExportedNames に重複する要素が含まれているなら、構文エラー
- ModuleItemList の ExportedBindings の要素が、ModuleItemList の VarDeclaredNames または ModuleItemList の LexicallyDeclaredNames のどちらにも存在しないなら、構文エラー
- ModuleItemList Contains
super
なら、構文エラー - ModuleItemList Contains NewTarget なら、構文エラー
- 引数 « » を使用して ModuleItemList の ContainsDuplicateLabels が true なら、構文エラー
- 引数 « » を使用して ModuleItemList の ContainsUndefinedBreakTarget が true なら、構文エラー
- 引数 « » と « » を使用して ModuleItemList の ContainsUndefinedContinueTarget が true なら、構文エラー
15.2.1.2 静的セマンティクス(Static Semantics): ContainsDuplicateLabels
引数 labelSet を使用。
- 引数 labelSet を使用して ModuleItemList の ContainsDuplicateLabels を hasDuplicates とする
- hasDuplicates が true なら、 true を返す
- 引数 labelSet を使用して ModuleItem の ContainsDuplicateLabels の実行結果を返す
- false を返す
15.2.1.3 静的セマンティクス(Static Semantics): ContainsUndefinedBreakTarget
引数 labelSet を使用。
- 引数 labelSet を使用して ModuleItemList の ContainsUndefinedBreakTarget を hasUndefinedLabels とする
- hasUndefinedLabels が true なら、 true を返す
- 引数 labelSet を使用して ModuleItem の ContainsUndefinedBreakTarget の実行結果を返す
- false を返す
15.2.1.4 静的セマンティクス(Static Semantics): ContainsUndefinedContinueTarget
引数 iterationSet と labelSet を使用。
- 引数 iterationSet と « » を使用して ModuleItemList の ContainsUndefinedContinueTarget を hasUndefinedLabels とする
- hasUndefinedLabels が true なら、 true を返す
- 引数 iterationSet と « » を使用して ModuleItem の ContainsUndefinedContinueTarget の実行結果を返す
- false を返す
15.2.1.5 静的セマンティクス(Static Semantics): ExportedBindings
- ModuleItemList の ExportedBindings を names とする
- ModuleItem の ExportedBindings の要素を names に追加する
- names を返す
- 空の新規List を返す
15.2.1.6 静的セマンティクス(Static Semantics): ExportedNames
- ModuleItemList の ExportedNames を names とする
- ModuleItem の ExportedNames の要素を names に追加する
- names を返す
- ExportDeclaration の ExportedNames を返す
- 空の新規List を返す
15.2.1.7 静的セマンティクス(Static Semantics): ExportEntries
- 空の新規List を返す
- ModuleItemList の ExportEntries を entries とする
- ModuleItem の ExportEntries の要素を entries に追加する
- entries を返す
- 空の新規List を返す
15.2.1.8 静的セマンティクス(Static Semantics): ImportEntries
- 空の新規List を返す
- ModuleItemList の ImportEntries を entries とする
- ModuleItem の ImportEntries の要素を entries に追加する
- entries を返す
- 空の新規List を返す
15.2.1.9 静的セマンティクス(Static Semantics): ImportedLocalNames ( importEntries )
引数importEntriesを指定した抽象操作ImportedLocalNamesは、ImportEntryレコードのリストによって定義されたすべてのローカルネームバインディングのリストを作成します(表43を参照)。 ImportedLocalNamesは、次の手順を実行します。
- 空の新規List を localNames とする
- importEntries の 各 ImportEntryレコード を i とし、 i ごとに次を実行する
- localNames に i.[[LocalName]] を追加する
- localNames を返す
15.2.1.10 静的セマンティクス(Static Semantics): ModuleRequests
- 空の新規List を返す
- ModuleItem の ModuleRequests を返す
- ModuleItemList の ModuleRequests を moduleNames とする
- ModuleItem の ModuleRequests を additionalNames とする
- moduleNames に存在していない additionalNames の要素を moduleNames に追加する
- moduleNames を返す
- 空の新規List を返す
15.2.1.11 静的セマンティクス(Static Semantics): LexicallyDeclaredNames
- ModuleItemList の LexicallyDeclaredNames を names とする
- ModuleItem の LexicallyDeclaredNames の要素を names に追加する
- names を返す
- ImportDeclaration の BoundNames を返す
- ExportDeclaration が export VariableStatement なら、 空の新規List を返す
- ExportDeclaration の BoundNames を返す
- StatementListItem の LexicallyDeclaredNames を返す
15.2.1.12 静的セマンティクス(Static Semantics): LexicallyScopedDeclarations
- 空の新規List を返す
- ModuleItemList の LexicallyScopedDeclarations を declarations とする
- ModuleItem の LexicallyScopedDeclarations の要素を declarations に追加する
- declarations を返す
- 空の新規List を返す
15.2.1.13 静的セマンティクス(Static Semantics): VarDeclaredNames
- 空の新規List を返す
- ModuleItemList の VarDeclaredNames を names とする
- ModuleItem の VarDeclaredNames の要素を names に追加する
- names を返す
- 空の新規List を返す
- ExportDeclaration が export VariableStatement なら、 ExportDeclaration の BoundNames を返す
- 空の新規List を返す
15.2.1.14 静的セマンティクス(Static Semantics): VarScopedDeclarations
- 空の新規List を返す
- ModuleItemList の VarScopedDeclarations を declarations とする
- ModuleItem の VarScopedDeclarations の要素を declarations に追加する
- declarations を返す
- 空の新規List を返す
- ExportDeclaration が export VariableStatement なら、 VariableStatement の VarScopedDeclarations を返す
- 空の新規List を返す
15.2.1.15 抽象モジュールレコード(Abstract Module Records)
モジュールレコード
モジュールレコードは、単一モジュールのインポートとエクスポートに関する構造情報をカプセル化します。 この情報は、接続されたモジュールセットのインポートとエクスポートをリンクするために使用されます。 モジュールレコードには、モジュールを評価するときにのみ使用される4つのフィールドが含まれています。
仕様上、モジュールレコード値はRecord仕様型です。モジュールレコードが抽象サブクラスと具象サブクラスの両方を持つ抽象クラスである単純なオブジェクト指向階層に存在すると考えることができます。 この仕様は、Cyclicモジュールレコードという抽象サブクラスとソーステキストモジュールレコードという具象サブクラスを定義します。 他の仕様および実装では、定義した代替モジュール定義機能に対応する追加のモジュールレコードサブクラスを定義できます。
モジュールレコードは、表38にリストされているフィールドを持ちます。すべてのモジュール定義サブクラスは、これらのフィールドが含まれます。 モジュールレコードは、表39の抽象メソッドリストが定義されます。すべてのモジュール定義サブクラスは、これらのメソッドの具体的な実装を提供する必要があります。
フィールド名 | 値の型 | 意味 |
---|---|---|
[[Realm]] | レルムレコード | undefined |
モジュールが作成されたレルム。 まだ割り当てられていない場合はundefined。 |
[[Environment]] | レキシカル環境 | undefined |
モジュールの最上位バインディングを含むレキシカル環境。 モジュールがリンクされているときに設定されます。 |
[[Namespace]] | Object | undefined |
モジュール名前空間オブジェクト(26.3)(このモジュール用に作成されている場合)。 それ以外の場合はundefinedです。 |
[[HostDefined]] | 不特定 デフォルトはundefined |
モジュールに関連付けられた追加情報。ホスト環境で使用するために予約されたフィールド。 |
メソッド | 目的 |
---|---|
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のフィールドを持ちます。
フィールド名 | 値の型 | 意味 |
---|---|---|
[[Status]] | unlinked | linking | linked | evaluating | evaluated |
初期値はunlinked。 モジュールがライフサイクル全体にわたって進行するにつれて、 linking、linked、evaluating、evaluatedの順序で移行します。 |
[[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のメソッドを持ちます。
メソッド | 意味 |
---|---|
InitializeEnvironment() | インポートされたすべてのバインディングの解決を含め、モジュールのレキシカル環境を初期化し、モジュールの実行コンテキストを作成します。 |
ExecuteModule() | 実行コンテキスト内でモジュールのコードを評価します。 |
15.2.1.16.1 Link ( ) 具象メソッド(Concrete Method)
Cyclicモジュールレコード の Link具象メソッドは、対応するモジュールレコード抽象メソッドを実装します。
成功すると、Link はモジュールの [[Status]] を unlinked から linked に変更します。 失敗すると、例外がスローされ、モジュールの [[Status]] は unlinked のままになります。
この抽象メソッドは、次の手順を実行します(ほとんどの作業は補助関数InnerModuleLinkingによって実行されます)。
- Cyclicモジュールレコード を module とする
- Assert: module.[[Status]] は linking と evaluating ではない
- 空の新規List を stack とする
- InnerModuleLinking(module, stack, 0) を result とする
- result が 突然の完了 なら、
- stack の 各 Cyclicモジュールレコード を m とし、m ごとに次を実行する
- Assert: m.[[Status]] は linking
- unlinked を m.[[Status]] にセットする
- undefined を m.[[Environment]] にセットする
- undefined を m.[[DFSIndex]] にセットする
- undefined を m.[[DFSAncestorIndex]] にセットする
- Assert: module.[[Status]] は unlinked
- result を返す
- stack の 各 Cyclicモジュールレコード を m とし、m ごとに次を実行する
- Assert: module.[[Status]] は linked か evaluated
- Assert: stack は empty
- undefined を返す
15.2.1.16.1.1 InnerModuleLinking ( module, stack, index )
InnerModuleLinking抽象操作は、Linkから呼び出されます。Cyclicモジュールレコードmodule の実際のリンクプロセスを実行します。また、依存関係グラフ内の他のすべてのモジュールに対して再帰的に実行します。 stackとindex、および<モジュールの[[DFSIndex]]フィールドと[[DFSAncestorIndex]]フィールドは、深さ優先探索(DFS)トラバーサルを追跡します。 特に、[[DFSAncestorIndex]]は、強連結成分(SCC)内のすべてのモジュールが相互にリンクさせるために、SCCを検出する目的で使用されます。
この抽象操作は、次の手順を実行します。
- module が a Cyclicモジュールレコード でないなら、
- ? module.Link() を実行する
- index を返す
- module.[[Status]] が linking、 linked か evaluated なら、
- index を返す
- Assert: module.[[Status]] は unlinked
- linking を module.[[Status]] にセットする
- index を module.[[DFSIndex]] にセットする
- index を module.[[DFSAncestorIndex]] にセットする
- index + 1 を index にセットする
- stack に module を追加する
- module.[[RequestedModules]] の 各文字列要素を required とし、required ごとに次を実行する
- ? HostResolveImportedModule(module, required) を requiredModule とする
- ? InnerModuleLinking(requiredModule, stack, index) を index にセットする
- requiredModule が Cyclicモジュールレコード なら、
- ? module.InitializeEnvironment() を実行する
- Assert: module は stack で1回のみ発生
- Assert: module.[[DFSAncestorIndex]] は module.[[DFSIndex]] 以下
- module.[[DFSAncestorIndex]] イコール module.[[DFSIndex]] なら、
- false を done とする
- done が false に間繰り返す
- stack の最後の要素を requiredModule とする
- stack の最後の要素を削除する
- Assert: requiredModule は Cyclicモジュールレコード
- linked を requiredModule.[[Status]] にセットする
- requiredModule と module が 同じモジュールレコード なら、 true を done にセットする
- index を返す
15.2.1.16.2 Evaluate ( ) 具象メソッド(Concrete Method)
Cyclicモジュールレコードの具体的な評価メソッドは、対応するモジュールコード抽象メソッドを実装します。Evaluateはモジュールの[[Status]]を linked から evaluated に変更します。例外が発生した場合、その例外が[[EvaluationError]]フィールドに記録され、Evaluateが再度呼び出されたとき再度スローされます。
この抽象メソッドは、次の手順を実行します(ほとんどの作業は補助関数InnerModuleEvaluationによって実行されます)。
- Assert: Evaluate呼び出しは、同時に周囲のエージェント内で呼び出されていない
- Cyclicモジュールレコード を module とする
- Assert: module.[[Status]] は linked または evaluated
- 空の新規List を stack とする
- InnerModuleEvaluation(module, stack, 0) を result とする
- result が 突然の完了 なら、
- stack の 各要素を Cyclicモジュールレコード m とし、 Cyclicモジュールレコード m ごとに次を実行する
- Assert: m.[[Status]] は evaluating
- evaluated を m.[[Status]] にセットする
- result を m.[[EvaluationError]] にセットする
- Assert: module.[[Status]] は evaluated で module.[[EvaluationError]] は result
- result を返す
- stack の 各要素を Cyclicモジュールレコード m とし、 Cyclicモジュールレコード m ごとに次を実行する
- Assert: module.[[Status]] は evaluated で module.[[EvaluationError]] は undefined
- Assert: stack は empty
- undefined を返す
15.2.1.16.2.1 InnerModuleEvaluation ( module, stack, index )
InnerModuleEvaluation抽象操作は、Evaluateから呼び出されます。ソーステキストモジュールレコード moduleの実際の評価プロセスを実行するだけでなく、依存関係グラフ内の他のすべてのモジュールに対して再帰的に実行されます。 stackとindex、およびmoduleの[[DFSIndex]]フィールドと[[DFSAncestorIndex]]フィールドは、InnerModuleLinkingと同じ方法で使用されます。
- module が Cyclicモジュールレコード でないなら、
- module.[[Status]] が evaluated なら、
- module.[[EvaluationError]] が undefined なら、 index を返す
- module.[[EvaluationError]] を返す
- module.[[Status]] が evaluating なら、index を返す
- Assert: module.[[Status]] は linked
- evaluating を module.[[Status]] にセットする
- index を module.[[DFSIndex]] にセットする
- index を module.[[DFSAncestorIndex]] にセットする
- index + 1 を index にセットする
- stack に module を追加する
- module.[[RequestedModules]] の 各String要素を required とし、required ごとに次を実行する
- ! HostResolveImportedModule(module, required) を requiredModule とする
- NOTE: このメソッドを呼び出す前に Link が正常に完了する必要がある。そのため要求されたすべてのモジュールが正常に解決されることが保証される。
- ? InnerModuleEvaluation(requiredModule, stack, index) を index にセットする
- requiredModule が Cyclicモジュールレコード なら、
- ? module. ExecuteModule() を実行する
- Assert: module は stack で1回のみ発生
- Assert: module.[[DFSAncestorIndex]] は module[[DFSIndex]] 以下
- module.[[DFSAncestorIndex]] イコール module.[[DFSIndex]] なら
- false を done とする
- done が false の間繰り返し
- stack の最後の要素を requiredModule とする
- stack の最後の要素を削除する
- Assert: requiredModule は Cyclicモジュールレコード
- evaluated を requiredModule.[[Status]] にセットする
- requiredModule と module が同じ モジュールレコード なら true を done にセット
- index を返す
15.2.1.16.3 Cyclicモジュールレコードグラフの例(Example Cyclic Module Record Graphs)
このセクションは非規範的です。ここではエラーがどのように発生するかに特に焦点を当てて、いくつかの一般的なモジュールグラフのリンクと評価の一連の例を示します。
まず、次の単純なモジュールグラフについて考えます。
簡単なモジュールグラフ
エラー状態がないと仮定します。 ホストが最初にA.Link()を呼び出し正常に完了したとき、A.[[Status]] = B.[[Status]] = C.[[Status]] = linked のようにモジュールBとCが再帰的にリンクします。この準備ステップはいつでも実行できます。 後で、ホストがモジュールの副作用をおこす準備ができたら、A.Evaluate()を呼び出して、最初のCとBを再帰的に評価して、正常に完了します。各モジュールの[[Status]]は、この時点でevaluated になります。
次に、リンクエラーを伴うケースを考えてみます。 CのInnerModuleLinkingは成功したが、その後Bで失敗した場合(例:Cが提供しないものをインポートした)、元のA.Link()は失敗し、AとBの[[Status]]は unlinked のままになります。 ただし、Cの[[ステータス]]は linked です。
最後に、評価エラーを伴うケースを考えてみます。 CのInnerModuleEvaluationが成功したが、その後Bが失敗した場合(例:Bに例外をスローするコードが含まれている)、元のA.Evaluate()は失敗します。 結果として生じる例外は、AとBの両方の[[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()はAでInnerModuleLinkingを実行します。これにより、BでもInnerModuleLinkingが呼び出されます。サイクルのため、AでInnerModuleLinkingが再度トリガーされます。 しかし、A.[[Status]]はすでに linking のため、この時点では何も実行されません。 B.[[Status]]自体は、制御がAに戻り、CでInnerModuleLinkingがトリガーされたときに linking を維持します。c.[[Status]]が linked で戻った後、AとBの両方がlinking から linked に移行します。 これらは強く接続されたコンポーネントを形成するための仕様です。
成功した場合、Cyclicモジュールグラフの評価フェーズでも同様の現象が起こります。
ここで、Aにリンクエラーがある場合を考えてみます。 たとえば、存在しないCからバインディングをインポートしたケースです。 この場合、AのInnerModuleLinkingへの2回目の呼び出しからの早期復帰を含め、上記の手順は引き続き発生します。ただし、Aの元のInnerModuleLinkingに戻ると、InitializeEnvironment中、つまりC.ResolveExport()の直後に失敗します。 スローされたSyntaxError例外は、A.Linkまで伝播します。これにより、現在stack上にあるすべてのモジュールがリセットされます(これらは、常にlinkingのモジュールと同じです)。 したがって、AとBの両方が unlinked になります。 Cはlinkedのままであることに注意してください。
最後に、Aに評価エラーがある場合を考えます。 たとえば、ソースコードが例外をスローしたケースです。 この場合、上記のステップの評価時間アナログは、2 回目の呼び出しにおけるAのInnerModuleEvaluationへの早期復帰を含め、依然として発生します。ただし、Aで元のInnerModuleEvaluationに戻ると、失敗します。 スローされた例外はA.Evaluate()まで伝播します。これは、現在stack上にあるすべてのモジュール(つまり、evaluatingのモジュール)のエラーを記録します。 したがって、AとBの両方がevaluatedになり、例外がAとBの両方の[[EvaluationError]]フィールドに記録されます。Cは[[EvaluationError]]なしでevaluatedのままになります。
15.2.1.17 ソーステキストモジュールレコード(Source Text Module Records)
ソーステキストモジュールレコード
ソーステキストモジュールレコードは、ゴールシンボルModuleを使用して解析されたECMAScriptソーステキスト(10)で定義されたモジュールに関する情報を保持するために使用されます。 フィールドには、モジュールによってインポートされた名前に関するダイジェスト情報が含まれます。また、具象メソッドは、モジュールをリンク、リンク、および評価するためにダイジェスト情報を使用します。
ソーステキストモジュールレコードは、抽象モジュールレコード 型の他のサブクラスとともにモジュールグラフに存在できます。また、Cyclicモジュールレコード 型の他のサブクラスとともにサイクルに参加できます。
ソーステキストモジュールレコードは、表40に加えて、表42の追加フィールドを持ちます。これらの各フィールドは、最初はParseModuleで設定されます。
フィールド名 | 値の型 | 意味 |
---|---|---|
[[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で定義されているフィールドがあります。
フィールド名 | 値の型 | 意味 |
---|---|---|
[[ModuleRequest]] | String | ImportDeclaration の ModuleSpecifier のString値 |
[[ImportName]] | String | [[ModuleRequest]]で識別されるモジュールによってエクスポートされるバインディングの名前。 値 "*" は、インポート要求がターゲットモジュールの名前空間オブジェクトに対するものであることを示します。 |
[[LocalName]] | String | インポートモジュール内からインポートされた値を、ローカルからアクセスするために使用される名前。 |
表44に、Import構文で使用されるImportEntryレコードフィールドの例を示します。
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で定義されているフィールドがあります。
フィールド名 | 値の型 | 意味 |
---|---|---|
[[ExportName]] | String | null |
バインディングをエクスポートするために使用される名前。 |
[[ModuleRequest]] | String | null |
ExportDeclarationのModuleSpecifierの文字列値。 ExportDeclarationにModuleSpecifierがない場合はnull。 |
[[ImportName]] | String | null |
[[ModuleRequest]]で識別されるモジュールによって目的のバインディングがエクスポートされる名前。 ExportDeclarationにModuleSpecifierがない場合はnull。 "*" は、エクスポート要求がすべてのエクスポートされたバインディングに対するものであることを示します。 |
[[LocalName]] | String | null |
インポートモジュールがエクスポートした値にローカルからアクセスするために使用される名前。 エクスポートされた値がモジュール内からローカルにアクセスできない場合はnull。 |
表46に、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" | "*" | null |
export * as ns from "mod"; |
"ns" | "mod" | "*" | null |
以降の定義は、ソーステキストモジュールレコードの具象メソッドとその他の抽象操作を指定します。
15.2.1.17.1 ParseModule ( sourceText, realm, hostDefined )
引数sourceText, realm, hostDefinedを指定した抽象操作ParseModuleは、sourceTextをModuleとして解析した結果に基づいてソーステキストモジュールレコードを作成します。 ParseModuleは、次の手順を実行します。
- Assert: sourceText は ECMAScriptソーステキスト
- Moduleをゴールシンボル として使用してsourceTextを解析します。 解析が成功し、早期エラーが見つからなかった場合は、結果の解析ツリーをbodyとします。 それ以外の場合は、解析エラーや早期エラーを表す1つ以上のSyntaxErrorオブジェクトのリストをbodyとします。 解析と早期エラーは、実装に依存する方法で検出される場合があります。 複数の解析エラーまたは早期エラーが存在する場合、リスト内のエラーオブジェクトの数と順序は実装に依存します。
- body が エラーのList なら body を返す
- body の ModuleRequests を requestedModules とする
- body の ImportEntries を importEntries とする
- ImportedLocalNames(importEntries) を importedBoundNames とする
- 空の新規List を indirectExportEntries とする
- 空の新規List を localExportEntries とする
- 空の新規List を starExportEntries とする
- body の ExportEntries を exportEntries とする
- exportEntries の 各 ExportEntryレコード 要素を ee とし、 ee ごとに次を実行する
- ee.[[ModuleRequest]] が null なら、
- ee.[[LocalName]] が importedBoundNames の要素でないなら、
- localExportEntries に ee を追加する
- i. と異なるなら、
- [[LocalName]] が ee.[[LocalName]] と同じ importEntries の要素を ie とする
- ie.[[ImportName]] が "*" なら、
- NOTE: これは、インポートされたモジュール名前空間オブジェクトの再エクスポート
- localExportEntries に ee を追加する
- 2. と異なるなら、
- NOTE: これは単一名の再エクスポートです
- indirectExportEntries に ExportEntryレコード { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } を追加する
- ee.[[LocalName]] が importedBoundNames の要素でないなら、
- a. と異なり、 if ee.[[ImportName]] が "*" で ee.[[ExportName]] が null なら、
- starExportEntries に ee を追加する
- b. と異なるなら、
- indirectExportEntries に ee を追加する
- ee.[[ModuleRequest]] が null なら、
- ソーステキストモジュールレコード { [[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 } を返す
15.2.1.17.2 GetExportedNames ( [ exportStarSet ] ) 具象メソッド(Concrete Method)
ソーステキストモジュールレコードのGetExportedNames具象メソッドは、対応するモジュールレコード抽象メソッドを実装します。
- exportStarSet が 存在しないなら、 空の新規List を exportStarSet にセットする
- Assert: exportStarSet は ソーステキストモジュールレコード のリスト
- ソーステキストモジュールレコード を module とする
- exportStarSet に module が含まれるなら、
- exportStarSet に module を追加する
- 空の新規List を exportedNames とする
- module.[[LocalExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
- Assert: moduleは、このエクスポートの直接バインディングを提供する
- exportedNames に e.[[ExportName]] を追加する
- module.[[IndirectExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
- Assert: module は、このエクスポートの特定のバインディングをインポートする
- exportedNames に e.[[ExportName]] を追加する
- module.[[StarExportEntries]] の各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
- ? HostResolveImportedModule(module, e.[[ModuleRequest]]) を requestedModule とする
- ? requestedModule.GetExportedNames(exportStarSet) を starNames とする
- starNames の 各要素を n とし、n ごとに次を実行する
- SameValue(n, "default") が false なら、
- n が exportedNames の要素でないなら、
- exportedNames に n を追加する
- n が exportedNames の要素でないなら、
- SameValue(n, "default") が false なら、
- exportedNames を返す
15.2.1.17.3 ResolveExport ( exportName [ , resolveSet ] ) 具象メソッド(Concrete Method)
ソーステキストモジュールレコードのResolveExport具象メソッドは、対応するモジュールレコード抽象メソッドを実装します。
ResolveExportは、インポートされたバインディングを実際の定義モジュールとローカルバインディング名で解決します。 定義モジュールは、このメソッドが呼び出されたモジュールレコード、またはモジュールによってインポートされた他のモジュールです。 パラメータresolveSetは、未解決の循環インポート/エクスポートパスを検出するために使用されます。 特定のモジュールレコードとexportNameがすでにresolveSetにセットされている場合、インポートの循環が発生しています。 ResolveExportを再帰的に呼び出す前に、moduleとexportNameで構成されるペアがresolveSetに追加されます。
定義モジュールがある場合、ResolvedBindingレコード {[[Module]],[[BindingName]]}が返されます。 このレコードが、ローカルバインディングを持たない名前空間のエクスポートでない限り、最初に要求されたエクスポートの解決されたバインディングを識別します。 この場合、[[BindingName]]は "*namespace*" に設定されます。 定義がない場合、またはリクエストが循環している場合は、nullが返されます。 要求があいまいであることが判明した場合、文字列 "ambiguous" が返されます。
この抽象メソッドは、次の手順を実行します。
- resolveSet が存在しないなら、 空の新規List を resolveSet にセットする
- Assert: resolveSet は Record { [[Module]], [[ExportName]] } のリスト
- ソーステキストモジュールレコード を module とする
- resolveSet の 各 Record { [[Module]], [[ExportName]] } 要素を r とし、 r ごとに次を実行する
- resolveSet に Record { [[Module]]: module, [[ExportName]]: exportName } を追加する
- module.[[LocalExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
- SameValue(exportName, e.[[ExportName]]) が true なら、
- Assert:module は、このエクスポートの直接バインディングを提供する
- ResolvedBindingレコード { [[Module]]: module, [[BindingName]]: e.[[LocalName]] } を返す
- SameValue(exportName, e.[[ExportName]]) が true なら、
- module.[[IndirectExportEntries]] の各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
- SameValue(exportName, e.[[ExportName]]) が true なら、
- ? HostResolveImportedModule(module, e.[[ModuleRequest]]) を importedModule とする
- e.[[ImportName]] が "*" なら、
- Assert: moduleは、このエクスポートの直接バインディングを提供しない
- ResolvedBindingレコード { [[Module]]: importedModule, [[BindingName]]: "*namespace*" } を返す
- ii. と異なるなら、
- Assert: moduleは、このエクスポートの特定のバインディングをインポートする
- importedModule.ResolveExport(e.[[ImportName]], resolveSet) を返す
- SameValue(exportName, e.[[ExportName]]) が true なら、
- SameValue(exportName, "default") が true なら、
- Assert: デフォルトのエクスポートが、このモジュールによって明示的に定義されていない
- null を返す
- NOTE: デフォルトのエクスポートは、export * または export * from "mod" 宣言では提供できない
- null を starResolution とする
- module.[[StarExportEntries]] の 各 ExportEntryレコード 要素を e とし、 ExportEntryレコード e ごとに次を実行する
- ? HostResolveImportedModule(module, e.[[ModuleRequest]]) を importedModule とする
- ? importedModule.ResolveExport(exportName, resolveSet) を resolution とする
- resolution の "ambiguous" なら "ambiguous" を返す
- resolution が null でないなら、
- Assert: resolution は ResolvedBindingレコード
- starResolution が null なら、 resolution を starResolution にセットする
- ii. と異なるなら、
- starResolution を返す
15.2.1.17.4 InitializeEnvironment ( ) 具象メソッド(Concrete Method)
ソーステキストモジュールレコード のInitializeEnvironment具象メソッドは、対応するCyclicモジュールレコード の抽象メソッドを実装します。
この抽象メソッドは、次の手順を実行します。
- this ソーステキストモジュールレコード を module とする
- module.[[IndirectExportEntries]] の 各 ExportEntryレコード 要素を e とし、 e ごとに次を実行する
- ? module.ResolveExport(e.[[ExportName]]) を resolution とする
- resolution が null または "ambiguous" なら SyntaxError例外をスローする
- Assert: resolution は ResolvedBindingレコード
- Assert: moduleからのすべての名前付きエクスポートが解決可能
- module.[[Realm]] を realm とする
- Assert: realm は undefined ではない
- NewModuleEnvironment(realm.[[GlobalEnv]]) を env とする
- env を module.[[Environment]] にセットする
- env の EnvironmentRecord を envRec とする
- module.[[ImportEntries]] の 各 ImportEntryレコード 要素を in とし、 in ごとに次を実行する
- ! HostResolveImportedModule(module, in.[[ModuleRequest]]) を importedModule とする
- NOTE: インポートされたモジュール要求はmodule.[[RequestedModules]]のサブセットであり、これらはこのアルゴリズムの初期の段階で解決されているため、上記の呼び出しは失敗しない
- in.[[ImportName]] が "*" なら、
- ? GetModuleNamespace(importedModule) を namespace とする
- ! envRec. CreateImmutableBinding(in.[[LocalName]], true) を実行する
- envRec.InitializeBinding(in.[[LocalName]], namespace) をコール
- c. と異なるなら、
- ? importedModule.ResolveExport(in.[[ImportName]]) を resolution とする
- resolution が null または "ambiguous" なら SyntaxError例外をスローする
- resolution.[[BindingName]] が "*namespace*" なら、
- ? GetModuleNamespace(resolution.[[Module]]) を namespace とする
- ! envRec. CreateImmutableBinding(in.[[LocalName]], true) を実行する
- envRec.InitializeBinding(in.[[LocalName]], namespace) をコール
- iii. と異なるなら、
- envRec.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]) をコール
- 新規 ECMAScriptコード実行コンテキスト を moduleContext とする
- null を moduleContext の Functionコンポーネント にセットする
- Assert: module.[[Realm]] は undefined ではない
- module を moduleContext の Realmコンポーネント にセットする [[Realm]]
- module を moduleContext の ScriptOrModuleコンポーネント にセットする
- module を moduleContext の VariableEnvironmentコンポーネント にセットする [[Environment]]
- module を moduleContext の LexicalEnvironmentコンポーネント にセットする [[Environment]]
- moduleContext を module.[[Context]] にセットする
- moduleContext を 実行コンテキストスタックにプッシュする。moduleContextが実行中の実行コンテキストになる
- module.[[ECMAScriptCode]] を code とする
- code の VarScopedDeclarations を varDeclarations とする
- 空の新規List を declaredVarNames とする
- varDeclarations の 各要素を d とし、d ごとに次を実行する
- d の BoundNames の各要素を dn とし、dn ごとに次を実行する
- dn が declaredVarNames の要素でないなら、
- ! envRec.CreateMutableBinding(dn, false) を実行する
- envRec. InitializeBinding(dn, undefined) をコール
- declaredVarNames に dn を追加する
- dn が declaredVarNames の要素でないなら、
- d の BoundNames の各要素を dn とし、dn ごとに次を実行する
- code の LexicallyScopedDeclarations を lexDeclarations とする
- lexDeclarations の 各要素を d とし、d ごとに次を実行する
- d の BoundNames の 各要素を dn とし、dn ごとに次を実行する
- d の IsConstantDeclaration が true なら、
- ! envRec. CreateImmutableBinding(dn, true) を実行する
- i. と異なるなら、
- ! envRec. CreateMutableBinding(dn, false) を実行する
- d が FunctionDeclaration または GeneratorDeclaration または AsyncFunctionDeclaration または AsyncGeneratorDeclaration なら、
- 引数 env を使用して d の InstantiateFunctionObject を fo とする
- envRec.InitializeBinding(dn, fo) をコールする
- d の IsConstantDeclaration が true なら、
- d の BoundNames の 各要素を dn とし、dn ごとに次を実行する
- 実行コンテキストスタック から moduleContext を削除する
- NormalCompletion(empty) を返す
15.2.1.17.5 ExecuteModule ( ) 具象メソッド(Concrete Method)
ソーステキストモジュールレコードのExecuteModule具象メソッドは、対応するCyclicモジュールレコード 抽象メソッドを実装します。
この抽象メソッドは、次の手順を実行します。
- ソーステキストモジュールレコード を module とする
- 現在の実行中の実行コンテキスト を Suspendする
- module.[[Context]] を moduleContext とする
- moduleContext を 実行コンテキストスタック にプッシュする。moduleContext が 実行中の実行コンテキスト になる
- module.[[ECMAScriptCode]] の評価結果を result とする
- moduleContext を Suspend し、実行コンテキストスタックから削除する
- 実行コンテキストスタック の最上位にあるコンテキストを 実行中の実行コンテキスト として再開する
- Completion(result) を返す
15.2.1.18 ランタイムセマンティクス(Runtime Semantics): HostResolveImportedModule ( referencingScriptOrModule, specifier )
HostResolveImportedModuleは、スクリプトレコードまたはモジュールレコード の referencingScriptOrModule にに対応するスクリプトまたはモジュールのコンテキスト内で発生するModuleSpecifier String、specifierに対応する具体的なモジュールレコードサブクラスインスタンスを提供する実装定義の抽象操作です。 import() 式のコンテキストで解決が実行されており、その時点でアクティブなスクリプトまたはモジュールがない場合、referencingScriptOrModule はnullになる可能性があります。
Webブラウザーホストで、次のようなコントロールをクリックすると、
<button type="button" onclick="import('./foo.mjs')">Click me</button>
import() 式の実行時には、アクティブなスクリプトまたはモジュールはありません。 より一般的には、これは、ホストがnullのScriptOrModuleコンポーネントを含む実行コンテキストを実行コンテキストスタックにプッシュする状況で発生する可能性があります。
HostResolveImportedModuleの実装は、次の要件に準拠する必要があります。
- 通常の戻り値は、モジュールレコード の具象サブクラスのインスタンスである必要があります。
- ScriptOrModule、specifier に対応するモジュールレコードが存在しないか、作成できない場合は、例外をスローする必要があります。
- 同じ referencingScriptOrModule、specifierのペアが引数として呼び出されたら、同じモジュールレコードインスタンスを返す必要があります。(正常に完了した場合)
複数の異なるreferenceingScriptOrModule、specifierのペアは、同じモジュールレコードインスタンスにマップされる場合があります。 実際のマッピングセマンティクスは実装によって定義されますが、通常、正規化プロセスはマッピングプロセスの一部としてspecifierに適用されます。 典型的な正規化プロセスには、アルファベットの大文字小文字の区別や、相対パス指定子と省略パス指定子の展開などのアクションが含まれます。
15.2.1.19 ランタイムセマンティクス(Runtime Semantics): HostImportModuleDynamically ( referencingScriptOrModule, specifier, promiseCapability )
referenceingScriptOrModuleは、スクリプトレコードまたはモジュールレコードです。specifierは、referenceingScriptOrModuleに対応するスクリプトまたはモジュールのコンテキスト内で発生するModuleSpecifierの文字列です。HostImportModuleDynamicallyは実装定義の抽象操作で、specifierに対応するモジュールを使用可能にするために必要なセットアップ作業を実行します。(import()式が発生したときにアクティブなスクリプトまたはモジュールがない場合、referencingScriptOrModuleはnullになる可能性があります。)次に、FinishDynamicImportを実行して、動的インポートプロセスを終了します。
HostImportModuleDynamicallyの実装は、次の要件に準拠する必要があります。
- 抽象操作は、常にundefinedで正常に完了する必要があります。 代わりに、以下で説明するように、成功または失敗を通知する必要があります
- ホスト環境は、次の2つの要件セットのいずれかに準拠している必要があります。
成功時:
- 将来的には、ホスト環境で次を実行する必要があります
FinishDynamicImport(referencingScriptOrModule, specifier, promiseCapability, NormalCompletion(undefined))
- 引数referencingScriptOrModuleとspecifierを指定して、FinishDynamicImportが完了した後のHostResolveImportedModuleへの後続の呼び出しは、正常に完了する必要があります。
- 引数referencingScriptOrModuleとspecifierを指定して、FinishDynamicImportが完了した後のHostResolveImportedModuleへの後続呼び出しの完了値は、評価済モジュールである必要があります。つまり、Evaluate具象メソッドがすでに呼び出され、通常の完了を返している必要があります。
失敗時:
- 将来的には、ホスト環境でFinishDynamicImport(referencingScriptOrModule, specifier, promiseCapability、突然の完了) を実行する必要があります。突然の完了は失敗の原因を表します。
- 将来的には、ホスト環境で次を実行する必要があります
- ホスト環境が特定のreferencingScriptOrModule、specifierペアに対して一度成功した場合、再呼び出しでも成功する必要があります。
- 操作は、promiseCapability.[[Resolve]]またはpromiseCapability.[[Reject]]を呼び出さないでください。代わりに、promiseCapabilityをFinishDynamicImportに渡される不透明な識別値として扱う必要があります。
実際のプロセスは実装によって定義されます。通常、HostResolveImportedModuleが適切なモジュールコードを同期的に取得するために必要なI/O操作を実行し、Evaluate具象メソッドを呼び出すことで構成されます。 これには、HostResolveImportedModuleと同様の正規化が必要な場合があります。
15.2.1.20 ランタイムセマンティクス(Runtime Semantics): FinishDynamicImport ( referencingScriptOrModule, specifier, promiseCapability, completion )
FinishDynamicImportは、元々import() 呼び出しによって開始された動的インポートのプロセスを完了し、completionに従って、その呼び出しが返したプロミスを解決または拒否します。 これは、HostImportModuleDynamicallyの一部としてホスト環境によって実行されます。
- completion が 突然の完了 なら、 ! Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] ») を実行する
- 1. と異なるなら、
- Assert: completion は正常完了で、 completion[[Value]] は undefined
- ! HostResolveImportedModule(referencingScriptOrModule, specifier) を moduleRecord とする
- Assert: EvaluateはmoduleRecordで呼び出し済みで、正常に完了している
- GetModuleNamespace(moduleRecord) を namespace とする
- namespace が 突然の完了 なら、 ! Call(promiseCapability.[[Reject]], undefined, « namespace.[[Value]] ») を実行する
- e. と異なるなら、 ! Call(promiseCapability.[[Resolve]], undefined, « namespace.[[Value]] ») を実行する
15.2.1.21 ランタイムセマンティクス(Runtime Semantics): GetModuleNamespace ( module )
GetModuleNamespace抽象操作は、moduleのエクスポートを表すモジュール名前空間オブジェクトを取得します。ただし、初回要求時は遅延作成し、将来の取得のためにmodule.[[Namespace]]に格納します。
この抽象操作は、次の手順を実行します。
- Assert: module は モジュールレコード の具象サブクラスのインスタンス
- Assert: module が Cyclicモジュールレコード なら、 module[[Status]] は unlinked ではない
- module.[[Namespace]] を namespace とする
- namespace が undefined なら、
- ? module.GetExportedNames() を exportedNames とする
- 空の新規List を unambiguousNames とする
- exportedNames の各要素を name とし、name ごとに次を実行する
- ? module.ResolveExport(name) を resolution とする
- resolution が ResolvedBindingレコード なら、unambiguousNames に name を追加する
- ModuleNamespaceCreate(module, unambiguousNames) を namespace にセットする
- namespace を返す
15.2.1.22 ランタイムセマンティクス:評価(Runtime Semantics: Evaluation)
- NormalCompletion(undefined) を返す
- ModuleItemList の評価結果を result とする
- result.[[Type]] が normal and result.[[Value]] is empty なら、
- NormalCompletion(undefined) を返す
- Completion(result) を返す
- ModuleItemList の評価結果を sl とする
- ReturnIfAbrupt(sl)
- ModuleItem の評価結果を s とする
- Completion( UpdateEmpty(s, sl)) を返す
- NormalCompletion(empty) を返す
15.2.2 Imports
構文:
15.2.2.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)
- ImportDeclaration の BoundNames に重複する要素が含まれているなら、構文エラー
15.2.2.2 静的セマンティクス(Static Semantics): BoundNames
- ImportClause の BoundNames を返す
- 空の新規List を返す
- ImportedDefaultBinding の BoundNames を names とする
- NameSpaceImport の BoundNames の要素を names に追加する
- names を返す
- ImportedDefaultBinding の BoundNames を names とする
- NamedImports の BoundNames の要素を names に追加する
- names を返す
- 空の新規List を返す
- ImportsList の BoundNames を names とする
- ImportSpecifier の BoundNames の要素を names に追加する
- names を返す
- ImportedBinding の BoundNames を返す
15.2.2.3 静的セマンティクス(Static Semantics): ImportEntries
- FromClause の ModuleRequests の唯一の要素を module とする
- 引数 module を使用して ImportClause の ImportEntriesForModule の実行結果を返す
- 空の新規List を返す
15.2.2.4 静的セマンティクス(Static Semantics): ImportEntriesForModule
引数 module を使用。
- 引数 module を使用して ImportedDefaultBinding の ImportEntriesForModule を entries とする
- 引数 module を使用して NameSpaceImport の ImportEntriesForModule の要素を entries に追加する
- entries を返す
- 引数 module を使用して ImportedDefaultBinding の ImportEntriesForModule を entries とする
- 引数 module を使用して NamedImports の ImportEntriesForModule の要素を entries に追加する
- entries を返す
- ImportedBinding の BoundNames の唯一の要素を localName とする
- ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName } を defaultEntry とする
- defaultEntry を含む新規List を返す
- ImportedBinding の StringValue を localName とする
- ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: localName } を entry とする
- entry を含む新規List を返す
- 空の新規List を返す
- 引数 module を使用して ImportsList の ImportEntriesForModule を specs とする
- 引数 module を使用して ImportSpecifier の ImportEntriesForModule の要素を specs に追加する
- specs を返す
- ImportedBinding の BoundNames の唯一の要素を localName とする
- ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName } を entry とする
- entry を含む新規List を返す
- IdentifierName の StringValue を importName とする
- ImportedBinding の StringValue を localName とする
- ImportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName } を entry とする
- entry を含む新規List を返す
15.2.2.5 静的セマンティクス(Static Semantics): ModuleRequests
- FromClause の ModuleRequests を返す
- StringLiteral の StringValue を含む Listを返す
15.2.3 Exports
構文:
15.2.3.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)
- NamedExportsのReferencedBindingsの各IdentifierNameを n とする。n の StringValue が ReservedWordであるか、"implements"、"interface"、"let"、"package"、"private"、"protected"、"public"、 "static" のどれかなら、構文エラー。
15.2.3.2 静的セマンティクス(Static Semantics): BoundNames
- 空の新規List を返す
- VariableStatement の BoundNames を返す
- Declaration の BoundNames を返す
- HoistableDeclaration の BoundNames を declarationNames とする
- declarationNames に "*default*" が含まれていないなら、declarationNames に "*default*" を追加する
- declarationNames を返す
- ClassDeclaration の BoundNames を declarationNames とする
- declarationNames に "*default*"が含まれていないなら、declarationNames に "*default*" を追加する
- declarationNames を返す
15.2.3.3 静的セマンティクス(Static Semantics): ExportedBindings
- 空の新規List を返す
- NamedExports の ExportedBindings を返す
- VariableStatement の BoundNames を返す
- Declaration の BoundNames を返す
- ExportDeclaration の BoundNames を返す
- 空の新規List を返す
- ExportsList の ExportedBindings を names とする
- ExportSpecifier の ExportedBindings の要素を names に追加する
- names を返す
- IdentifierName の StringValue を含む Listを返す
- 最初の IdentifierName の StringValue を含む Listを返す
15.2.3.4 静的セマンティクス(Static Semantics): ExportedNames
- ExportFromClause の ExportedNames を返す
- 空の新規List を返す
- IdentifierName の StringValue を含む Listを返す
- NamedExports の ExportedNames を返す
- VariableStatement の BoundNames を返す
- Declaration の BoundNames を返す
- 空の新規List を返す
- ExportsList の ExportedNames を names とする
- ExportSpecifier の ExportedNames の要素を names に追加する
- names を返す
- IdentifierName の StringValue を含む Listを返す
- 2番目の IdentifierName の StringValue を含む Listを返す
15.2.3.5 静的セマンティクス(Static Semantics): ExportEntries
- FromClause の ModuleRequests の唯一の要素を module とする
- 引数 module を使用して ExportFromClause の ExportEntriesForModule の実行結果を返す
- 引数 null を使用して NamedExports の ExportEntriesForModule の実行結果を返す
- 空の新規List を entries とする
- VariableStatement の BoundNames を names とする
- names の 各要素を name とし、name ごとに次を実行する
- entries に ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } を追加する
- entries を返す
- 空の新規List を entries とする
- Declaration の BoundNames を names とする
- names の 各要素を name とし、name ごとに次を実行する
- entries に ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } を追加する
- entries を返す
- HoistableDeclaration の BoundNames を names とする
- names の唯一の要素を localName とする
- ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } を含む新しいリストを返す
- ClassDeclaration の BoundNames を names とする
- names の唯一の要素を localName とする
- ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" } を含む新しいリストを返す
- ExportEntryレコード { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: "*default*", [[ExportName]]: "default" } を entry とする
- entry を含む新規List を返す
15.2.3.6 静的セマンティクス(Static Semantics): ExportEntriesForModule
引数 module を使用。
- ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: null, [[ExportName]]: null } を entry とする
- entry を含む新規List を返す
- IdentifierName の StringValue を exportName とする
- ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: null, [[ExportName]]: exportName } を entry とする
- entry を含む新規List を返す
- 空の新規List を返す
- 引数 module を使用して ExportsList の ExportEntriesForModule を specs とする
- 引数 module を使用して ExportSpecifier の ExportEntriesForModule の要素を specs に追加する
- specs を返す
- IdentifierName の StringValue を sourceName とする
- module が null なら、
- sourceName を localName とする
- null を importName とする
- 11. と異なるなら、
- null を localName とする
- sourceName を importName とする
- ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: sourceName } を含む新しいリストを返す
- 最初の IdentifierName の StringValue を sourceName とする
- 2番目の IdentifierName の StringValue を exportName とする
- module が null なら、
- sourceName を localName とする
- null を importName とする
- undefined. と異なるなら、
- null を localName とする
- sourceName を importName とする
- ExportEntryレコード { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: exportName } を含む新しいリストを返す
15.2.3.7 静的セマンティクス(Static Semantics): IsConstantDeclaration
- false を返す
15.2.3.8 静的セマンティクス(Static Semantics): LexicallyScopedDeclarations
- 空の新規List を返す
- Declaration の DeclarationPart を含む新しいリストを返す
- HoistableDeclaration の DeclarationPart を含む新しいリストを返す
- ClassDeclaration を含む新しいリストを返す
- ExportDeclaration を含む新しいリストを返す
15.2.3.9 静的セマンティクス(Static Semantics): ModuleRequests
- FromClause の ModuleRequests を返す
- 空の新規List を返す
15.2.3.10 静的セマンティクス(Static Semantics): ReferencedBindings
- 空の新規List を返す
- ExportsList の ReferencedBindings を names とする
- ExportSpecifier の ReferencedBindings の要素を names に追加する
- names を返す
- IdentifierName を含むリストを返す
- 最初の IdentifierName を含むリストを返す
15.2.3.11 ランタイムセマンティクス:評価(Runtime Semantics: Evaluation)
- NormalCompletion(empty) を返す
- VariableStatement の 評価結果を返す
- Declaration の 評価結果を返す
- HoistableDeclaration の 評価結果を返す
- ClassDeclaration の ? BindingClassDeclarationEvaluation を value とする
- ClassDeclaration の BoundNames の唯一の要素を className とする
- className が "*default*" なら、
- 実行中の実行コンテキスト の LexicalEnvironment を env とする
- ? InitializeBoundName("*default*", value, env) を実行する
- NormalCompletion(empty) を返す
- IsAnonymousFunctionDefinition(AssignmentExpression ) が true なら、
- 引数 "default" を使用して AssignmentExpression の NamedEvaluation を value とする
- 9. と異なるなら、
- AssignmentExpression の評価結果を rhs とする
- ? GetValue(rhs) を value とする
- 実行中の実行コンテキスト の LexicalEnvironment を env とする
- ? InitializeBoundName("*default*", value, env) を実行する
- NormalCompletion(empty) を返す