From 99447eebb9c84d70c03bece97cd67e36be1fdddc Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Thu, 11 May 2017 16:34:11 -0400 Subject: [PATCH 01/29] Store and rethrow module instantiation/evaluation errors This addresses #862 by ensuring that repeated calls to ModuleDeclarationInstantiation() and ModuleEvaluation(), for Source Text Module Records, rethrow any exceptions they previously threw, instead of silently succeeding. This allows host environments to do top-down instantiation/evaluation of module graphs, instead of having to do bottom-up instantiation/evaluation in order to record individual failures and thus prevent future instantiation/evaluation. In the process, this helps formalize some of the invariants previously stated in a vague way, such as "ModuleDeclarationInstantiation must have completed successfully", replacing them instead with an explicit [[Status]] field whose contents can be asserted against. For background on the trouble caused by the previous approach of silent success, see: - https://github.com/whatwg/html/issues/1545 - https://github.com/tc39/ecma262/issues/862 - https://github.com/whatwg/html/issues/2629 --- spec.html | 150 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 55 deletions(-) diff --git a/spec.html b/spec.html index 2125efa52a..1cb13eb7e5 100644 --- a/spec.html +++ b/spec.html @@ -20989,13 +20989,24 @@

Abstract Module Records

- [[Evaluated]] + [[Status]] - Boolean + String + + + Initially `"uninstantiated"`. Can become `"instantiated"`, `"instantiating"`, `"evaluated"`, or `"errored"` as the module progresses throughout its lifecycle. + + + + + [[ErrorCompletion]] + + + An abrupt completion - Initially *false*, *true* if evaluation of this module has started. Remains *true* when evaluation completes, even if it is an abrupt completion. + A completion record representing exception that occurred during instantiation or evaluation; meaningful only if [[Status]] is `"errored"`. @@ -21044,7 +21055,7 @@

Abstract Module Records

ModuleDeclarationInstantiation() - Transitively resolve all module dependencies and create a module Environment Record for the module. + Transitively resolve all module dependencies and create a module Environment Record for the module. Will transition this module's [[Status]] from `"uninstantiated"` to either `"instantiated"` or `"errored"`. While this is executing, this module's [[Status]] will be `"instantiating"`; this is observable through reentrant invocations via circular dependencies. @@ -21052,8 +21063,8 @@

Abstract Module Records

ModuleEvaluation() -

Do nothing if this module has already been evaluated. Otherwise, transitively evaluate all module dependences of this module and then evaluate this module.

-

ModuleDeclarationInstantiation must be completed prior to invoking this method.

+

Transitively evaluate all module dependences of this module and then evaluate this module.

+

Will transition this module's [[Status]] from `"instantiated"` to either `"evaluated"` or `"errored"`; if the status is already in one of those states, do nothing or return [[ErrorCompletion]] as appropriate. This method will never be invoked when the module's status is `"uninstantiated"`.

@@ -21646,52 +21657,73 @@

ModuleDeclarationInstantiation( ) Concrete Method

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record performs the following steps:

1. Let _module_ be this Source Text Module Record. - 1. Let _realm_ be _module_.[[Realm]]. - 1. Assert: _realm_ is not *undefined*. - 1. Let _code_ be _module_.[[ECMAScriptCode]]. - 1. If _module_.[[Environment]] is not *undefined*, return NormalCompletion(~empty~). - 1. Let _env_ be NewModuleEnvironment(_realm_.[[GlobalEnv]]). - 1. Set _module_.[[Environment]] to _env_. - 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do - 1. NOTE: Before instantiating a module, all of the modules it requested must be available. An implementation may perform this test at any time prior to this point. - 1. Let _requiredModule_ be ? HostResolveImportedModule(_module_, _required_). - 1. Perform ? _requiredModule_.ModuleDeclarationInstantiation(). - 1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do - 1. Let _resolution_ be ? _module_.ResolveExport(_e_.[[ExportName]], « »). - 1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception. - 1. Assert: All named exports from _module_ are resolvable. - 1. Let _envRec_ be _env_'s EnvironmentRecord. - 1. For each ImportEntry Record _in_ in _module_.[[ImportEntries]], do - 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _in_.[[ModuleRequest]]). - 1. NOTE: The above call cannot fail because imported module requests are a subset of _module_.[[RequestedModules]], and these have been resolved earlier in this algorithm. - 1. If _in_.[[ImportName]] is `"*"`, then - 1. Let _namespace_ be ? GetModuleNamespace(_importedModule_). - 1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). - 1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). - 1. Else, - 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], « »). + 1. Let _result_ be InnerModuleDeclarationInstantiation(_module_). + 1. If _result_ is an abrupt completion, + 1. Set _module_.[[Status]] to `"errored"`. + 1. Set _module_.[[ErrorCompletion]] to _result_. + 1. Otherwise, set _module_.[[Status]] to `"instantiated"`. + 1. Return _result_. + + + +

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_ )

+

The InnerModuleDeclarationInstantiation abstract operation performs the following steps:

+ + 1. Let _realm_ be _module_.[[Realm]]. + 1. Assert: _realm_ is not *undefined*. + 1. Let _code_ be _module_.[[ECMAScriptCode]]. + 1. If _module_.[[Status]] is `"errored"`, return _module_.[[ErrorCompletion]]. + 1. If _module_.[[Status]] is `"instantiating"`, `"instantiated"` or `"evaluated"`, + 1. Assert: _module_.[[Environment]] is not *undefined*. + 1. Return NormalCompletion(~empty~). + 1. Assert: _module_.[[Status]] is `"uninstantiated"`. + 1. Let _env_ be NewModuleEnvironment(_realm_.[[GlobalEnv]]). + 1. Set _module_.[[Environment]] to _env_. + 1. Set _module_.[[Status]] to `"instantiating"`. + 1. For each String _required_ that is an element of _module_.[[RequestedModules]], + 1. NOTE: Before instantiating a module, all of the modules it requested must be available. An implementation may perform this test at any time prior to this point. + 1. Perform ? HostResolveImportedModule(_module_, _required_). + 1. For each String _required_ that is an element of _module_.[[RequestedModules]], + 1. NOTE: this loop is separate from the previous one to ensure that exceptions due to unresolvable modules are thrown before attempting to instantiate any modules. + 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). + 1. Perform ? _requiredModule_.ModuleDeclarationInstantiation(). + 1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do + 1. Let _resolution_ be ? _module_.ResolveExport(_e_.[[ExportName]], « »). 1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception. - 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). - 1. Let _varDeclarations_ be the VarScopedDeclarations of _code_. - 1. Let _declaredVarNames_ be a new empty List. - 1. For each element _d_ in _varDeclarations_, do - 1. For each element _dn_ of the BoundNames of _d_, do - 1. If _dn_ is not an element of _declaredVarNames_, then - 1. Perform ! _envRec_.CreateMutableBinding(_dn_, *false*). - 1. Call _envRec_.InitializeBinding(_dn_, *undefined*). - 1. Append _dn_ to _declaredVarNames_. - 1. Let _lexDeclarations_ be the LexicallyScopedDeclarations of _code_. - 1. For each element _d_ in _lexDeclarations_, do - 1. For each element _dn_ of the BoundNames of _d_, do - 1. If IsConstantDeclaration of _d_ is *true*, then - 1. Perform ! _envRec_.CreateImmutableBinding(_dn_, *true*). + 1. Assert: All named exports from _module_ are resolvable. + 1. Let _envRec_ be _env_'s EnvironmentRecord. + 1. For each ImportEntry Record _in_ in _module_.[[ImportEntries]], do + 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _in_.[[ModuleRequest]]). + 1. NOTE: The above call cannot fail because imported module requests are a subset of _module_.[[RequestedModules]], and these have been resolved earlier in this algorithm. + 1. If _in_.[[ImportName]] is `"*"`, then + 1. Let _namespace_ be ? GetModuleNamespace(_importedModule_). + 1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). + 1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, - 1. Perform ! _envRec_.CreateMutableBinding(_dn_, *false*). - 1. If _d_ is a |FunctionDeclaration|, a |GeneratorDeclaration|, or an |AsyncFunctionDeclaration|, then - 1. Let _fo_ be the result of performing InstantiateFunctionObject for _d_ with argument _env_. - 1. Call _envRec_.InitializeBinding(_dn_, _fo_). - 1. Return NormalCompletion(~empty~). - + 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], « »). + 1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception. + 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). + 1. Let _varDeclarations_ be the VarScopedDeclarations of _code_. + 1. Let _declaredVarNames_ be a new empty List. + 1. For each element _d_ in _varDeclarations_, do + 1. For each element _dn_ of the BoundNames of _d_, do + 1. If _dn_ is not an element of _declaredVarNames_, then + 1. Perform ! _envRec_.CreateMutableBinding(_dn_, *false*). + 1. Call _envRec_.InitializeBinding(_dn_, *undefined*). + 1. Append _dn_ to _declaredVarNames_. + 1. Let _lexDeclarations_ be the LexicallyScopedDeclarations of _code_. + 1. For each element _d_ in _lexDeclarations_, do + 1. For each element _dn_ of the BoundNames of _d_, do + 1. If IsConstantDeclaration of _d_ is *true*, then + 1. Perform ! _envRec_.CreateImmutableBinding(_dn_, *true*). + 1. Else, + 1. Perform ! _envRec_.CreateMutableBinding(_dn_, *false*). + 1. If _d_ is a |FunctionDeclaration|, a |GeneratorDeclaration|, or an |AsyncFunctionDeclaration|, then + 1. Let _fo_ be the result of performing InstantiateFunctionObject for _d_ with argument _env_. + 1. Call _envRec_.InitializeBinding(_dn_, _fo_). + 1. Return NormalCompletion(~empty~). + +
@@ -21700,14 +21732,18 @@

ModuleEvaluation( ) Concrete Method

The ModuleEvaluation concrete method of a Source Text Module Record performs the following steps:

1. Let _module_ be this Source Text Module Record. - 1. Assert: ModuleDeclarationInstantiation has already been invoked on _module_ and successfully completed. 1. Assert: _module_.[[Realm]] is not *undefined*. - 1. If _module_.[[Evaluated]] is *true*, return *undefined*. - 1. Set _module_.[[Evaluated]] to *true*. + 1. Assert: _module_.[[Status]] is not `"uninstantiated"` or `"instantiating"`. + 1. If _module_.[[Status]] is `"evaluated"`, return *undefined*. + 1. If _module_.[[Status]] is `"errored"`, return _module_.[[ErrorCompletion]]. 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). - 1. NOTE: ModuleDeclarationInstantiation must be completed prior to invoking this method, so every requested module is guaranteed to resolve successfully. - 1. Perform ? _requiredModule_.ModuleEvaluation(). + 1. NOTE: ModuleDeclarationInstantiation must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. + 1. Let _requiredModuleStatus_ be _requiredModule_.ModuleEvaluation(). + 1. If _requiredModuleStatus_ is an abrupt completion, + 1. Set _module_.[[Status]] to `"errored"`. + 1. Set _module_.[[ErrorCompletion]] to _requiredModuleStatus_. + 1. Return _requiredModuleStatus_. 1. Let _moduleCxt_ be a new ECMAScript code execution context. 1. Set the Function of _moduleCxt_ to *null*. 1. Set the Realm of _moduleCxt_ to _module_.[[Realm]]. @@ -21720,6 +21756,10 @@

ModuleEvaluation( ) Concrete Method

1. Let _result_ be the result of evaluating _module_.[[ECMAScriptCode]]. 1. Suspend _moduleCxt_ and remove it from the execution context stack. 1. Resume the context that is now on the top of the execution context stack as the running execution context. + 1. If _result_ is an abrupt completion, + 1. Set _module_.[[Status]] to `"errored"`. + 1. Set _module_.[[ErrorCompletion]] to _result_. + 1. Otherwise, set _module_.[[Status]] to `"evaluated"`. 1. Return Completion(_result_).
From 8cbe21bf012ec1ff0af97dc77db9e0941ff6fe5a Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Thu, 18 May 2017 19:06:14 +0200 Subject: [PATCH 02/29] Fix module instantiation and evaluation. --- spec.html | 207 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 151 insertions(+), 56 deletions(-) diff --git a/spec.html b/spec.html index 1cb13eb7e5..65ee37f145 100644 --- a/spec.html +++ b/spec.html @@ -20995,7 +20995,7 @@

Abstract Module Records

String - Initially `"uninstantiated"`. Can become `"instantiated"`, `"instantiating"`, `"evaluated"`, or `"errored"` as the module progresses throughout its lifecycle. + Initially `"uninstantiated"`. Can become `"instantiating"`, `"instantiated"`, `"evaluating"`, `"evaluated"`, or `"errored"` as the module progresses throughout its lifecycle. @@ -21003,10 +21003,10 @@

Abstract Module Records

[[ErrorCompletion]] - An abrupt completion + An abrupt completion | *undefined* - A completion record representing exception that occurred during instantiation or evaluation; meaningful only if [[Status]] is `"errored"`. + A completion of type `"throw"` representing the exception that occurred during instantiation or evaluation, if [[Status]] is `"errored"`. Otherwise *undefined*. @@ -21055,7 +21055,8 @@

Abstract Module Records

ModuleDeclarationInstantiation() - Transitively resolve all module dependencies and create a module Environment Record for the module. Will transition this module's [[Status]] from `"uninstantiated"` to either `"instantiated"` or `"errored"`. While this is executing, this module's [[Status]] will be `"instantiating"`; this is observable through reentrant invocations via circular dependencies. +

Transitively resolve all module dependencies and create a module Environment Record for the module.

+

Will transition this module's [[Status]] from `"uninstantiated"` to either `"instantiated"` or `"errored"`. While this is executing, this module's [[Status]] will be `"instantiating"`; this is observable through reentrant invocations via circular dependencies.

@@ -21063,8 +21064,10 @@

Abstract Module Records

ModuleEvaluation() -

Transitively evaluate all module dependences of this module and then evaluate this module.

-

Will transition this module's [[Status]] from `"instantiated"` to either `"evaluated"` or `"errored"`; if the status is already in one of those states, do nothing or return [[ErrorCompletion]] as appropriate. This method will never be invoked when the module's status is `"uninstantiated"`.

+

Transitively evaluate all module dependencies of this module and then evaluate this module.

+

Will transition this module's [[Status]] from + `"instantiated"` to either `"evaluated"` or `"errored"`. While + this is executing, this module's [[Status]] will be `"evaluating"`; this is observable through reentrant invocations via circular dependencies.

@@ -21157,6 +21160,29 @@

Source Text Module Records

A List of ExportEntry records derived from the code of this module that correspond to export * declarations that occur within the module. + + + [[DFSIndex]] + + + Integer | *undefined* + + + Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. + If [[Status]] is "`instantiating`" or "`evaluating`", this non-negative number records the point at which the module was first visited during the ongoing depth-first traversal of the dependency graph. + + + + + [[DFSAncestorIndex]] + + + Integer | *undefined* + + + Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. If [[Status]] is "`instantiating`" or "`evaluating`", this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component. + + @@ -21571,7 +21597,7 @@

ParseModule ( _sourceText_, _realm_, _hostDefined_ )

1. Append _ee_ to _starExportEntries_. 1. Else, 1. Append _ee_ to _indirectExportEntries_. - 1. Return Source Text Module Record {[[Realm]]: _realm_, [[Environment]]: *undefined*, [[HostDefined]]: _hostDefined_, [[Namespace]]: *undefined*, [[Evaluated]]: *false*, [[ECMAScriptCode]]: _body_, [[RequestedModules]]: _requestedModules_, [[ImportEntries]]: _importEntries_, [[LocalExportEntries]]: _localExportEntries_, [[StarExportEntries]]: _starExportEntries_, [[IndirectExportEntries]]: _indirectExportEntries_}. + 1. Return Source Text Module Record {[[Realm]]: _realm_, [[Environment]]: *undefined*, [[Namespace]]: *undefined*, [[Status]]: `"uninstantiated"`, [[ErrorCompletion]]: *undefined*, [[HostDefined]]: _hostDefined_, [[ECMAScriptCode]]: _body_, [[RequestedModules]]: _requestedModules_, [[ImportEntries]]: _importEntries_, [[LocalExportEntries]]: _localExportEntries_, [[IndirectExportEntries]]: _indirectExportEntries_, [[StarExportEntries]]: _starExportEntries_, [[DFSIndex]]: *undefined*, [[DFSAncestorIndex]]: *undefined*}.

An implementation may parse module source text and analyse it for Early Error conditions prior to the evaluation of ParseModule for that module source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseModule upon that source text.

@@ -21657,40 +21683,68 @@

ModuleDeclarationInstantiation( ) Concrete Method

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record performs the following steps:

1. Let _module_ be this Source Text Module Record. - 1. Let _result_ be InnerModuleDeclarationInstantiation(_module_). + 1. Assert: _module_.[[Status]] is not `"instantiating"` or `"evaluating"`. + 1. Let _stack_ be an empty list. + 1. Let _result_ be InnerModuleDeclarationInstantiation(_module_, _stack_, 0). 1. If _result_ is an abrupt completion, - 1. Set _module_.[[Status]] to `"errored"`. - 1. Set _module_.[[ErrorCompletion]] to _result_. - 1. Otherwise, set _module_.[[Status]] to `"instantiated"`. + 1. For each module _m_ in _stack_, + 1. Assert: _m_.[[Status]] is `"instantiating"`. + 1. Set _m_.[[Status]] to `"errored"`. + 1. Set _m_.[[ErrorCompletion]] to _result_. + 1. Assert: _module_.[[Status]] is `"errored"` and _module_.[[ErrorCompletion]] is _result_. + 1. Return _result_. + 1. Assert: _module_.[[Status]] is `"instantiated"` or `"evaluated"`. + 1. Assert: _stack_ is empty. 1. Return _result_. -

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_ )

+

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _index_ )

The InnerModuleDeclarationInstantiation abstract operation performs the following steps:

- 1. Let _realm_ be _module_.[[Realm]]. - 1. Assert: _realm_ is not *undefined*. - 1. Let _code_ be _module_.[[ECMAScriptCode]]. - 1. If _module_.[[Status]] is `"errored"`, return _module_.[[ErrorCompletion]]. - 1. If _module_.[[Status]] is `"instantiating"`, `"instantiated"` or `"evaluated"`, - 1. Assert: _module_.[[Environment]] is not *undefined*. - 1. Return NormalCompletion(~empty~). + 1. If _module_ is not a Source Text Module Record, + 1. If _module_.[[Status]] is `"instantiating"`, throw a *TypeError* exception. + 1. Otherwise, return _module_.ModuleDeclarationInstantiation(). + 1. If _module_.[[Status]] is `"instantiating"`, `"instantiated"`, or `"evaluated"`, + 1. Return *undefined*. + 1. If _module_.[[Status]] is `"errored"`, + 1. Return _module_.[[ErrorCompletion]]. 1. Assert: _module_.[[Status]] is `"uninstantiated"`. - 1. Let _env_ be NewModuleEnvironment(_realm_.[[GlobalEnv]]). - 1. Set _module_.[[Environment]] to _env_. 1. Set _module_.[[Status]] to `"instantiating"`. + 1. Set _module_.[[DFSIndex]] to _index_. + 1. Set _module_.[[DFSAncestorIndex]] to _index_. + 1. Append _module_ to _stack_. 1. For each String _required_ that is an element of _module_.[[RequestedModules]], - 1. NOTE: Before instantiating a module, all of the modules it requested must be available. An implementation may perform this test at any time prior to this point. - 1. Perform ? HostResolveImportedModule(_module_, _required_). - 1. For each String _required_ that is an element of _module_.[[RequestedModules]], - 1. NOTE: this loop is separate from the previous one to ensure that exceptions due to unresolvable modules are thrown before attempting to instantiate any modules. - 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). - 1. Perform ? _requiredModule_.ModuleDeclarationInstantiation(). + 1. Let _requiredModule_ be ? HostResolveImportedModule(_module_, _required_). + 1. Perform ? InnerModuleDeclarationInstantiation(_requiredModule_, _stack_, _index_+1). + 1. Assert: _requiredModule_.[[Status]] is either `"instantiating"`, `"instantiated"`, or `"evaluated"`. + 1. Assert: _requiredModule_.[[Status]] is "`instantiating`" if and only if _requiredModule_ is in _stack_. + 1. If _requiredModule_.[[Status]] is "`instantiating`", + 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]. + 1. Perform ? ModuleDeclarationResolution(_module_). + 1. Assert: _module_ occurs exactly once in _stack_. + 1. Assert: _module_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSIndex]]. + 1. If _module_.[[DFSAncestorIndex]] equals _module_.[[DFSIndex]], repeat: + 1. Let _requiredModule_ be the last element in _stack_. + 1. Remove this element from _stack_. + 1. Set _requiredModule_.[[Status]] to "`instantiated`". + 1. If _requiredModule_ is _module_, end the repetition. + 1. Return *undefined*. + +
+ + +

Runtime Semantics: ModuleDeclarationResolution( _module_ )

+

The ModuleDeclarationResolution abstract operation performs the following steps:

+ 1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do 1. Let _resolution_ be ? _module_.ResolveExport(_e_.[[ExportName]], « »). 1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception. 1. Assert: All named exports from _module_ are resolvable. + 1. Let _realm_ be _module_.[[Realm]]. + 1. Assert: _realm_ is not *undefined*. + 1. Let _env_ be NewModuleEnvironment(_realm_.[[GlobalEnv]]). + 1. Set _module_.[[Environment]] to _env_. 1. Let _envRec_ be _env_'s EnvironmentRecord. 1. For each ImportEntry Record _in_ in _module_.[[ImportEntries]], do 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _in_.[[ModuleRequest]]). @@ -21703,6 +21757,7 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_ )

1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], « »). 1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception. 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). + 1. Let _code_ be _module_.[[ECMAScriptCode]]. 1. Let _varDeclarations_ be the VarScopedDeclarations of _code_. 1. Let _declaredVarNames_ be a new empty List. 1. For each element _d_ in _varDeclarations_, do @@ -21721,7 +21776,6 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_ )

1. If _d_ is a |FunctionDeclaration|, a |GeneratorDeclaration|, or an |AsyncFunctionDeclaration|, then 1. Let _fo_ be the result of performing InstantiateFunctionObject for _d_ with argument _env_. 1. Call _envRec_.InitializeBinding(_dn_, _fo_). - 1. Return NormalCompletion(~empty~).
@@ -21732,36 +21786,76 @@

ModuleEvaluation( ) Concrete Method

The ModuleEvaluation concrete method of a Source Text Module Record performs the following steps:

1. Let _module_ be this Source Text Module Record. - 1. Assert: _module_.[[Realm]] is not *undefined*. - 1. Assert: _module_.[[Status]] is not `"uninstantiated"` or `"instantiating"`. - 1. If _module_.[[Status]] is `"evaluated"`, return *undefined*. - 1. If _module_.[[Status]] is `"errored"`, return _module_.[[ErrorCompletion]]. - 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do - 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). - 1. NOTE: ModuleDeclarationInstantiation must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. - 1. Let _requiredModuleStatus_ be _requiredModule_.ModuleEvaluation(). - 1. If _requiredModuleStatus_ is an abrupt completion, - 1. Set _module_.[[Status]] to `"errored"`. - 1. Set _module_.[[ErrorCompletion]] to _requiredModuleStatus_. - 1. Return _requiredModuleStatus_. - 1. Let _moduleCxt_ be a new ECMAScript code execution context. - 1. Set the Function of _moduleCxt_ to *null*. - 1. Set the Realm of _moduleCxt_ to _module_.[[Realm]]. - 1. Set the ScriptOrModule of _moduleCxt_ to _module_. - 1. Assert: _module_ has been linked and declarations in its module environment have been instantiated. - 1. Set the VariableEnvironment of _moduleCxt_ to _module_.[[Environment]]. - 1. Set the LexicalEnvironment of _moduleCxt_ to _module_.[[Environment]]. - 1. Suspend the currently running execution context. - 1. Push _moduleCxt_ on to the execution context stack; _moduleCxt_ is now the running execution context. - 1. Let _result_ be the result of evaluating _module_.[[ECMAScriptCode]]. - 1. Suspend _moduleCxt_ and remove it from the execution context stack. - 1. Resume the context that is now on the top of the execution context stack as the running execution context. + 1. Assert: _module_.[[Status]] is `"errored"`, `"instantiated"`, or `"evaluated"`. + 1. Let _stack_ be an empty list. + 1. Let _result_ be InnerModuleEvaluation(_module_, _stack_, 0). 1. If _result_ is an abrupt completion, - 1. Set _module_.[[Status]] to `"errored"`. - 1. Set _module_.[[ErrorCompletion]] to _result_. - 1. Otherwise, set _module_.[[Status]] to `"evaluated"`. - 1. Return Completion(_result_). + 1. For each module _m_ in _stack_, + 1. Assert: _m_.[[Status]] is `"evaluating"`. + 1. Set _m_.[[Status]] to `"errored"`. + 1. Set _m_.[[ErrorCompletion]] to _result_. + 1. Assert: _module_.[[Status]] is `"errored"` and _module_.[[ErrorCompletion]] is _result_. + 1. Return _result_. + 1. Assert: _module_.[[Status]] is `"evaluated"`. + 1. Assert: _stack_ is empty. + 1. Return _result_. + + +

Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

+

The InnerModuleEvaluation abstract operation performs the following steps:

+ + 1. If _module_ is not a Source Text Module Record, + 1. If _module_.[[Status]] is `"evaluating"`, throw a *TypeError* exception. + 1. Otherwise, return _module_.ModuleEvaluation(). + 1. If _module_.[[Status]] is `"evaluating"` or `"evaluated"`, + 1. Return *undefined*. + 1. If _module_.[[Status]] is `"errored"`, + 1. Return _module_.[[ErrorCompletion]]. + 1. Assert: _module_.[[Status]] is `"instantiated"`. + 1. Set _module_.[[Status]] to `"evaluating"`. + 1. Set _module_.[[DFSIndex]] to _index_. + 1. Set _module_.[[DFSAncestorIndex]] to _index_. + 1. Append _module_ to _stack_. + 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do + 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). + 1. NOTE: ModuleDeclarationInstantiation must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. + 1. Perform ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_+1). + 1. Assert: _requiredModule_.[[Status]] is either `"evaluating"` or `"evaluated"`. + 1. Assert: _requiredModule_.[[Status]] is "`evaluating`" if and only if _requiredModule_ is in _stack_. + 1. If _requiredModule_.[[Status]] is "`evaluating`", + 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]. + 1. Perform ? ModuleExecution(_module_). + 1. Assert: _module_ occurs exactly once in _stack_. + 1. Assert: _module_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSIndex]]. + 1. If _module_.[[DFSAncestorIndex]] equals _module_.[[DFSIndex]], repeat: + 1. Let _requiredModule_ be the last element in _stack_. + 1. Remove this element from _stack_. + 1. Set _requiredModule_.[[Status]] to "`evaluated`". + 1. If _requiredModule_ is _module_, end the repetition. + 1. Return *undefined*. + +
+ + +

Runtime Semantics: ModuleExecution( _module_ )

+

The ModuleExecution abstract operation performs the following steps:

+ + 1. Let _moduleCxt_ be a new ECMAScript code execution context. + 1. Set the Function of _moduleCxt_ to *null*. + 1. Assert: _module_.[[Realm]] is not *undefined*. + 1. Set the Realm of _moduleCxt_ to _module_.[[Realm]]. + 1. Set the ScriptOrModule of _moduleCxt_ to _module_. + 1. Assert: _module_ has been linked and declarations in its module environment have been instantiated. + 1. Set the VariableEnvironment of _moduleCxt_ to _module_.[[Environment]]. + 1. Set the LexicalEnvironment of _moduleCxt_ to _module_.[[Environment]]. + 1. Suspend the currently running execution context. + 1. Push _moduleCxt_ on to the execution context stack; _moduleCxt_ is now the running execution context. + 1. Let _result_ be the result of evaluating _module_.[[ECMAScriptCode]]. + 1. Suspend _moduleCxt_ and remove it from the execution context stack. + 1. Resume the context that is now on the top of the execution context stack as the running execution context. + +
@@ -21790,6 +21884,7 @@

Runtime Semantics: GetModuleNamespace( _module_ )

The abstract operation GetModuleNamespace called with argument _module_ performs the following steps:

1. Assert: _module_ is an instance of a concrete subclass of Module Record. + 1. Assert: _module_.[[Status]] is neither `"uninstantiated"` nor `"errored"`. 1. Let _namespace_ be _module_.[[Namespace]]. 1. If _namespace_ is *undefined*, then 1. Let _exportedNames_ be ? _module_.GetExportedNames(« »). From 2efb2f65f5c7c32dfccc2412bb5fc709990c2afb Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 30 May 2017 18:25:22 -0400 Subject: [PATCH 03/29] Tweaks --- spec.html | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/spec.html b/spec.html index 65ee37f145..ec1aeebc73 100644 --- a/spec.html +++ b/spec.html @@ -21006,7 +21006,7 @@

Abstract Module Records

An abrupt completion | *undefined* - A completion of type `"throw"` representing the exception that occurred during instantiation or evaluation, if [[Status]] is `"errored"`. Otherwise *undefined*. + A completion of type ~throw~ representing the exception that occurred during instantiation or evaluation, if [[Status]] is `"errored"`. Otherwise *undefined*. @@ -21065,9 +21065,7 @@

Abstract Module Records

Transitively evaluate all module dependencies of this module and then evaluate this module.

-

Will transition this module's [[Status]] from - `"instantiated"` to either `"evaluated"` or `"errored"`. While - this is executing, this module's [[Status]] will be `"evaluating"`; this is observable through reentrant invocations via circular dependencies.

+

Will transition this module's [[Status]] from `"instantiated"` to either `"evaluated"` or `"errored"`. While this is executing, this module's [[Status]] will be `"evaluating"`; this is observable through reentrant invocations via circular dependencies.

@@ -21180,7 +21178,7 @@

Source Text Module Records

Integer | *undefined* - Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. If [[Status]] is "`instantiating`" or "`evaluating`", this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component. + Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. If [[Status]] is "`instantiating`" or "`evaluating`", this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly-connected component. @@ -21684,7 +21682,7 @@

ModuleDeclarationInstantiation( ) Concrete Method

1. Let _module_ be this Source Text Module Record. 1. Assert: _module_.[[Status]] is not `"instantiating"` or `"evaluating"`. - 1. Let _stack_ be an empty list. + 1. Let _stack_ be a new empty List. 1. Let _result_ be InnerModuleDeclarationInstantiation(_module_, _stack_, 0). 1. If _result_ is an abrupt completion, 1. For each module _m_ in _stack_, @@ -21719,8 +21717,7 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ 1. Perform ? InnerModuleDeclarationInstantiation(_requiredModule_, _stack_, _index_+1). 1. Assert: _requiredModule_.[[Status]] is either `"instantiating"`, `"instantiated"`, or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`instantiating`" if and only if _requiredModule_ is in _stack_. - 1. If _requiredModule_.[[Status]] is "`instantiating`", - 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]. + 1. If _requiredModule_.[[Status]] is "`instantiating`", set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). 1. Perform ? ModuleDeclarationResolution(_module_). 1. Assert: _module_ occurs exactly once in _stack_. 1. Assert: _module_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSIndex]]. @@ -21787,7 +21784,7 @@

ModuleEvaluation( ) Concrete Method

1. Let _module_ be this Source Text Module Record. 1. Assert: _module_.[[Status]] is `"errored"`, `"instantiated"`, or `"evaluated"`. - 1. Let _stack_ be an empty list. + 1. Let _stack_ be a new empty List. 1. Let _result_ be InnerModuleEvaluation(_module_, _stack_, 0). 1. If _result_ is an abrupt completion, 1. For each module _m_ in _stack_, @@ -21820,11 +21817,10 @@

Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

1. For each String _required_ that is an element of _module_.[[RequestedModules]], do 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). 1. NOTE: ModuleDeclarationInstantiation must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. - 1. Perform ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_+1). + 1. Perform ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_ + 1). 1. Assert: _requiredModule_.[[Status]] is either `"evaluating"` or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`evaluating`" if and only if _requiredModule_ is in _stack_. - 1. If _requiredModule_.[[Status]] is "`evaluating`", - 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]. + 1. If _requiredModule_.[[Status]] is "`evaluating`", set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). 1. Perform ? ModuleExecution(_module_). 1. Assert: _module_ occurs exactly once in _stack_. 1. Assert: _module_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSIndex]]. From 0f36dba573290ca8d87298779e2d1e9ef04d91dd Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 30 May 2017 18:45:32 -0400 Subject: [PATCH 04/29] Assert no bad cycles, instead of throwing --- spec.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/spec.html b/spec.html index ec1aeebc73..9c44f817dd 100644 --- a/spec.html +++ b/spec.html @@ -21076,8 +21076,13 @@

Abstract Module Records

Source Text Module Records

+

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text (10) that was parsed using the goal symbol |Module|. Its fields contain digested information about the names that are imported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module.

+ +

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type. However, non-source text Module Records must not participate in dependency cycles with Source Text Module Records. Concretely, this is enforced below by assertions that non-source text Module Record dependencies do not have a [[Status]] of `"instantiating"` or `"evaluating"` during a call to ModuleDeclarationInstantiation or ModuleEvaluation on a Source Text Module Record.

+

In addition to the fields, defined in , Source Text Module Records have the additional fields listed in . Each of these fields initially has the value *undefined*.

+ @@ -21701,8 +21706,8 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _

The InnerModuleDeclarationInstantiation abstract operation performs the following steps:

1. If _module_ is not a Source Text Module Record, - 1. If _module_.[[Status]] is `"instantiating"`, throw a *TypeError* exception. - 1. Otherwise, return _module_.ModuleDeclarationInstantiation(). + 1. Assert: _module_.[[Status]] is not `"instantiating"`. + 1. Return _module_.ModuleDeclarationInstantiation(). 1. If _module_.[[Status]] is `"instantiating"`, `"instantiated"`, or `"evaluated"`, 1. Return *undefined*. 1. If _module_.[[Status]] is `"errored"`, @@ -21803,8 +21808,8 @@

Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

The InnerModuleEvaluation abstract operation performs the following steps:

1. If _module_ is not a Source Text Module Record, - 1. If _module_.[[Status]] is `"evaluating"`, throw a *TypeError* exception. - 1. Otherwise, return _module_.ModuleEvaluation(). + 1. Assert: _module_.[[Status]] is not `"evaluating"`. + 1. Return _module_.ModuleEvaluation(). 1. If _module_.[[Status]] is `"evaluating"` or `"evaluated"`, 1. Return *undefined*. 1. If _module_.[[Status]] is `"errored"`, From 2a7239fc38efac0f365ee9b4d7f0d6ea2e780e27 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 30 May 2017 18:46:53 -0400 Subject: [PATCH 05/29] Fix fake xref --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 9c44f817dd..6abbdf8e88 100644 --- a/spec.html +++ b/spec.html @@ -21077,7 +21077,7 @@

Abstract Module Records

Source Text Module Records

-

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text (10) that was parsed using the goal symbol |Module|. Its fields contain digested information about the names that are imported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module.

+

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text () that was parsed using the goal symbol |Module|. Its fields contain digested information about the names that are imported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module.

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type. However, non-source text Module Records must not participate in dependency cycles with Source Text Module Records. Concretely, this is enforced below by assertions that non-source text Module Record dependencies do not have a [[Status]] of `"instantiating"` or `"evaluating"` during a call to ModuleDeclarationInstantiation or ModuleEvaluation on a Source Text Module Record.

From f385bdf0451aeefb093f046938d175aebdc06c31 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 30 May 2017 18:48:05 -0400 Subject: [PATCH 06/29] Fix inaccurate note about initial value --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 6abbdf8e88..c5edbeb9b3 100644 --- a/spec.html +++ b/spec.html @@ -21081,7 +21081,7 @@

Source Text Module Records

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type. However, non-source text Module Records must not participate in dependency cycles with Source Text Module Records. Concretely, this is enforced below by assertions that non-source text Module Record dependencies do not have a [[Status]] of `"instantiating"` or `"evaluating"` during a call to ModuleDeclarationInstantiation or ModuleEvaluation on a Source Text Module Record.

-

In addition to the fields, defined in , Source Text Module Records have the additional fields listed in . Each of these fields initially has the value *undefined*.

+

In addition to the fields, defined in , Source Text Module Records have the additional fields listed in . Each of these fields is initially set in ParseModule.

From c1e0b9506796c03b9834b112b36a77150d89f4a6 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 30 May 2017 18:53:31 -0400 Subject: [PATCH 07/29] Make "Source Text Module Record" link to its dfn --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index c5edbeb9b3..0b4da71805 100644 --- a/spec.html +++ b/spec.html @@ -21077,7 +21077,7 @@

Abstract Module Records

Source Text Module Records

-

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text () that was parsed using the goal symbol |Module|. Its fields contain digested information about the names that are imported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module.

+

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text () that was parsed using the goal symbol |Module|. Its fields contain digested information about the names that are imported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module.

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type. However, non-source text Module Records must not participate in dependency cycles with Source Text Module Records. Concretely, this is enforced below by assertions that non-source text Module Record dependencies do not have a [[Status]] of `"instantiating"` or `"evaluating"` during a call to ModuleDeclarationInstantiation or ModuleEvaluation on a Source Text Module Record.

From 59d782a12aa17ac29aa691591c6fc5c287396b6f Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Fri, 2 Jun 2017 20:17:49 +0200 Subject: [PATCH 08/29] Assume HostResolveImportedModule never fails. --- spec.html | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/spec.html b/spec.html index 0b4da71805..5cc6cddc0a 100644 --- a/spec.html +++ b/spec.html @@ -21625,8 +21625,8 @@

GetExportedNames( _exportStarSet_ ) Concrete Method

1. Assert: _module_ imports a specific binding for this export. 1. Append _e_.[[ExportName]] to _exportedNames_. 1. For each ExportEntry Record _e_ in _module_.[[StarExportEntries]], do - 1. Let _requestedModule_ be ? HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). - 1. Let _starNames_ be ? _requestedModule_.GetExportedNames(_exportStarSet_). + 1. Let _requestedModule_ be ! HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). + 1. Let _starNames_ be ! _requestedModule_.GetExportedNames(_exportStarSet_). 1. For each element _n_ of _starNames_, do 1. If SameValue(_n_, `"default"`) is *false*, then 1. If _n_ is not an element of _exportedNames_, then @@ -21656,7 +21656,7 @@

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do 1. If SameValue(_exportName_, _e_.[[ExportName]]) is *true*, then 1. Assert: _module_ imports a specific binding for this export. - 1. Let _importedModule_ be ? HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). + 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). 1. Return ? _importedModule_.ResolveExport(_e_.[[ImportName]], _resolveSet_). 1. If SameValue(_exportName_, `"default"`) is *true*, then 1. Assert: A `default` export was not explicitly defined by this module. @@ -21664,7 +21664,7 @@

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

1. NOTE: A `default` export cannot be provided by an `export *`. 1. Let _starResolution_ be *null*. 1. For each ExportEntry Record _e_ in _module_.[[StarExportEntries]], do - 1. Let _importedModule_ be ? HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). + 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). 1. Let _resolution_ be ? _importedModule_.ResolveExport(_exportName_, _resolveSet_). 1. If _resolution_ is `"ambiguous"`, return `"ambiguous"`. 1. If _resolution_ is not *null*, then @@ -21718,7 +21718,7 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ 1. Set _module_.[[DFSAncestorIndex]] to _index_. 1. Append _module_ to _stack_. 1. For each String _required_ that is an element of _module_.[[RequestedModules]], - 1. Let _requiredModule_ be ? HostResolveImportedModule(_module_, _required_). + 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). 1. Perform ? InnerModuleDeclarationInstantiation(_requiredModule_, _stack_, _index_+1). 1. Assert: _requiredModule_.[[Status]] is either `"instantiating"`, `"instantiated"`, or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`instantiating`" if and only if _requiredModule_ is in _stack_. @@ -21750,7 +21750,9 @@

Runtime Semantics: ModuleDeclarationResolution( _module_ )

1. Let _envRec_ be _env_'s EnvironmentRecord. 1. For each ImportEntry Record _in_ in _module_.[[ImportEntries]], do 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _in_.[[ModuleRequest]]). - 1. NOTE: The above call cannot fail because imported module requests are a subset of _module_.[[RequestedModules]], and these have been resolved earlier in this algorithm. + 1. If _in_.[[ImportName]] is `"*"`, then 1. Let _namespace_ be ? GetModuleNamespace(_importedModule_). 1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). @@ -21888,7 +21890,7 @@

Runtime Semantics: GetModuleNamespace( _module_ )

1. Assert: _module_.[[Status]] is neither `"uninstantiated"` nor `"errored"`. 1. Let _namespace_ be _module_.[[Namespace]]. 1. If _namespace_ is *undefined*, then - 1. Let _exportedNames_ be ? _module_.GetExportedNames(« »). + 1. Let _exportedNames_ be ! _module_.GetExportedNames(« »). 1. Let _unambiguousNames_ be a new empty List. 1. For each _name_ that is an element of _exportedNames_, do 1. Let _resolution_ be ? _module_.ResolveExport(_name_, « »). From 6ae9fef6ffee52857783a8df47fad6003188ed7a Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Mon, 19 Jun 2017 13:30:26 +0200 Subject: [PATCH 09/29] Record error where it happens. --- spec.html | 63 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/spec.html b/spec.html index 5cc6cddc0a..a078e81897 100644 --- a/spec.html +++ b/spec.html @@ -8301,8 +8301,7 @@

[[Get]] ( _P_, _Receiver_ )

1. Let _exports_ be _O_.[[Exports]]. 1. If _P_ is not an element of _exports_, return *undefined*. 1. Let _m_ be _O_.[[Module]]. - 1. Let _binding_ be ? _m_.ResolveExport(_P_, « »). - 1. Assert: _binding_ is neither *null* nor `"ambiguous"`. + 1. Let _binding_ be ! _m_.ResolveExport(_P_, `"default"`, « »). 1. Let _targetModule_ be _binding_.[[Module]]. 1. Assert: _targetModule_ is not *undefined*. 1. Let _targetEnv_ be _targetModule_.[[Environment]]. @@ -21044,7 +21043,7 @@

Abstract Module Records

@@ -21182,7 +21183,7 @@

Source Text Module Records

Integer | *undefined* @@ -21637,35 +21638,32 @@

GetExportedNames( _exportStarSet_ ) Concrete Method

- -

Runtime Semantics: ResolutionFailure( _resolveMode_ )

-

The ResolutionFailure abstract operation performs the following steps:

- - 1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*. - 1. Assert: _resolveMode_ is `"normal"`. - 1. Throw a new *SyntaxError* exception. - -
- - -

Runtime Semantics: PropagateResolution( _module_, _resolution_ )

-

The PropagateResolution abstract operation performs the following steps:

- - 1. If _resolution_ is an abrupt completion, then - 1. If _module_.[[Status]] is `"errored"`, then - 1. Assert: _module_.[[ErrorCompletion]] is _resolution_. - 1. Otherwise, - 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. - 1. Set _module_.[[Status]] to `"errored"`. - 1. Set _module_.[[ErrorCompletion]] to _resolution_. - 1. Return _resolution_. - -
- -

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method

-

The ResolveExport concrete method of a Source Text Module Record with arguments _exportName_, _resolveMode_, and _resolveSet_ performs the following steps:

+

The ResolveExport concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

+ +

ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter _resolveSet_ is use to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and _exportName_ is reached that is already in _resolveSet_, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of _module_ and _exportName_ is added to _resolveSet_.

+ +

If a defining module is found, a ResolvedBinding Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export. If no definition is found or the request is found to be circular or ambiguous, an error is thrown or *undefined* is returned, depending on _resolveMode_ (see below for more details).

+ +

In addition to the standard _resolveMode_ values of `"normal"` or `"namespace"`, ResolveExport for Source Text Module Records also accepts a third value, `"star"`. This is only used when it calls itself recursively, in order to help implement the semantics of the `"normal"` mode.

+ +

Its failure behavior, when the _exportName_ cannot be resolved, varies among the different _resolveMode_ values:

+
+
`"normal"`
+
Throws a *SyntaxError* exception, which is recorded in the culprit module when applicable.
+ +
`"namespace"`
+
Returns *undefined*.
+ +
`"star"`
+
If a culprit module responsible for the unresolved name can be found, and has a recorded exception, it is rethrown. Otherwise, returns *undefined*.
+
+ +

(Note that if HostResolveImportedModule throws, the above analysis does not apply; such errors will be rethrown before any mode-specific logic is involved.)

+ +

This abstract method performs the following steps:

+ 1. Let _module_ be this Source Text Module Record. 1. Assert: _module_.[[Status]] is not `"errored"`. @@ -21705,16 +21703,49 @@

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method - -

ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter _resolveSet_ is use to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and _exportName_ is reached that is already in _resolveSet_, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of _module_ and _exportName_ is added to _resolveSet_.

-

If a defining module is found, a ResolvedBinding Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export. If no definition is found or the request is found to be circular or ambiguous, an error is thrown or *undefined* is returned, depending on _resolveMode_.

-
+ + +

Runtime Semantics: ResolutionFailure( _resolveMode_ )

+ +

The ResolutionFailure abstract operation is used by ResolveExport to react property to a module resolution failure in a given _resolveMode_.

+ +

This abstract operation performs the following steps:

+ + 1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*. + 1. Assert: _resolveMode_ is `"normal"`. + 1. Throw a new *SyntaxError* exception. + +
+ + +

Runtime Semantics: PropagateResolution( _module_, _resolution_ )

+ +

The PropagateResolution abstract operation is used by ResolveExport to ensure any module resolution failures from indirect or star exports are correctly propagated to the Source Text Module Record in question.

+ +

This abstract operation performs the following steps:

+ + 1. If _resolution_ is an abrupt completion, then + 1. If _module_.[[Status]] is `"errored"`, then + 1. Assert: _module_.[[ErrorCompletion]] is _resolution_. + 1. Otherwise, + 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. + 1. Set _module_.[[Status]] to `"errored"`. + 1. Set _module_.[[ErrorCompletion]] to _resolution_. + 1. Return _resolution_. + +

ModuleDeclarationInstantiation( ) Concrete Method

-

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record performs the following steps:

+ +

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

+ +

ModuleDeclarationInstantiation ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph.

+ +

This abstract method performs the following steps:

+ 1. Let _module_ be this Source Text Module Record. 1. Assert: _module_.[[Status]] is not `"instantiating"` or `"evaluating"`. @@ -21734,7 +21765,11 @@

ModuleDeclarationInstantiation( ) Concrete Method

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _index_ )

-

The InnerModuleDeclarationInstantiation abstract operation performs the following steps:

+ +

The InnerModuleDeclarationInstantiation abstract operation is used by ModuleDeclarationInstantiation to perform the actual instantiation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

+ +

This abstract operation performs the following steps:

+ 1. If _module_ is not a Source Text Module Record, 1. Assert: _module_.[[Status]] is not `"instantiating"`. @@ -21756,7 +21791,7 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ 1. Assert: _requiredModule_.[[Status]] is either `"instantiating"`, `"instantiated"`, or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`instantiating`" if and only if _requiredModule_ is in _stack_. 1. If _requiredModule_.[[Status]] is "`instantiating`", set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). - 1. Perform ? ModuleDeclarationResolution(_module_). + 1. Perform ? ModuleDeclarationEnvironmentSetup(_module_). 1. Assert: _module_ occurs exactly once in _stack_. 1. Assert: _module_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSIndex]]. 1. If _module_.[[DFSAncestorIndex]] equals _module_.[[DFSIndex]], repeat: @@ -21768,9 +21803,13 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ - -

Runtime Semantics: ModuleDeclarationResolution( _module_ )

-

The ModuleDeclarationResolution abstract operation performs the following steps:

+ +

Runtime Semantics: ModuleDeclarationEnvironmentSetup( _module_ )

+ +

The ModuleDeclarationEnvironmentSetup abstract operation is used by InnerModuleDeclarationInstantiation to initialize the Lexical Environment of the module, including resolving all imported bindings.

+ +

This abstract operation performs the following steps:

+ 1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do 1. Perform ? _module_.ResolveExport(_e_.[[ExportName]], `"normal"`, « »). @@ -21817,7 +21856,13 @@

Runtime Semantics: ModuleDeclarationResolution( _module_ )

ModuleEvaluation( ) Concrete Method

-

The ModuleEvaluation concrete method of a Source Text Module Record performs the following steps:

+ +

The ModuleEvaluation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

+ +

ModuleEvaluation ensures that if evaluation (the actual work for which is performed by InnerModuleEvaluation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph.

+ +

This abstract method performs the following steps:

+ 1. Let _module_ be this Source Text Module Record. 1. Assert: _module_.[[Status]] is `"errored"`, `"instantiated"`, or `"evaluated"`. @@ -21837,7 +21882,11 @@

ModuleEvaluation( ) Concrete Method

Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

-

The InnerModuleEvaluation abstract operation performs the following steps:

+ +

The InnerModuleEvaluation abstract operation is used by ModuleEvaluation to perform the actual evaluation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

+ +

This abstract operation performs the following steps:

+ 1. If _module_ is not a Source Text Module Record, 1. Assert: _module_.[[Status]] is not `"evaluating"`. @@ -21874,7 +21923,11 @@

Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

Runtime Semantics: ModuleExecution( _module_ )

-

The ModuleExecution abstract operation performs the following steps:

+ +

The ModuleExecution abstract operation is used by InnerModuleEvaluation to initialize the execution context of the module and evaluate the module's code within it.

+ +

This abstract operation performs the following steps:

+ 1. Let _moduleCxt_ be a new ECMAScript code execution context. 1. Set the Function of _moduleCxt_ to *null*. @@ -21913,10 +21966,13 @@

Runtime Semantics: HostResolveImportedModule ( _referencingModule_, _specifi

Multiple different _referencingModule_, _specifier_ pairs may map to the same Module Record instance. The actual mapping semantic is implementation-defined but typically a normalization process is applied to _specifier_ as part of the mapping process. A typical normalization process would include actions such as alphabetic case folding and expansion of relative and abbreviated path specifiers.

-

Runtime Semantics: GetModuleNamespace( _module_ )

-

The abstract operation GetModuleNamespace called with argument _module_ performs the following steps:

+ +

The GetModuleNamespace abstract operation retrieves the the Module Namespace Exotic object representing _module_'s exports, lazily creating it the first time it was requested, and storing it in _module_.[[Namespace]] for future retrieval.

+ +

This abstract operation performs the following steps:

+ 1. Assert: _module_ is an instance of a concrete subclass of Module Record. 1. Assert: _module_.[[Status]] is neither `"uninstantiated"` nor `"errored"`. From 643843d5aa76fd031874f5b240bbf49ae160e077 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 7 Jul 2017 18:01:51 -0400 Subject: [PATCH 22/29] More minor tweaks --- spec.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec.html b/spec.html index 6015885f90..2596ccdc9f 100644 --- a/spec.html +++ b/spec.html @@ -21742,7 +21742,7 @@

ModuleDeclarationInstantiation( ) Concrete Method

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

-

ModuleDeclarationInstantiation ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph.

+

ModuleDeclarationInstantiation ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller.

This abstract method performs the following steps:

@@ -21764,7 +21764,7 @@

ModuleDeclarationInstantiation( ) Concrete Method

-

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _index_ )

+

InnerModuleDeclarationInstantiation( _module_, _stack_, _index_ )

The InnerModuleDeclarationInstantiation abstract operation is used by ModuleDeclarationInstantiation to perform the actual instantiation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

@@ -21803,8 +21803,8 @@

Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ - -

Runtime Semantics: ModuleDeclarationEnvironmentSetup( _module_ )

+ +

ModuleDeclarationEnvironmentSetup( _module_ )

The ModuleDeclarationEnvironmentSetup abstract operation is used by InnerModuleDeclarationInstantiation to initialize the Lexical Environment of the module, including resolving all imported bindings.

@@ -21859,7 +21859,7 @@

ModuleEvaluation( ) Concrete Method

The ModuleEvaluation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

-

ModuleEvaluation ensures that if evaluation (the actual work for which is performed by InnerModuleEvaluation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph.

+

ModuleEvaluation ensures that if evaluation (the actual work for which is performed by InnerModuleEvaluation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller.

This abstract method performs the following steps:

@@ -21881,7 +21881,7 @@

ModuleEvaluation( ) Concrete Method

-

Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

+

InnerModuleEvaluation( _module_, _stack_, _index_ )

The InnerModuleEvaluation abstract operation is used by ModuleEvaluation to perform the actual evaluation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

@@ -21922,7 +21922,7 @@

Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

-

Runtime Semantics: ModuleExecution( _module_ )

+

ModuleExecution( _module_ )

The ModuleExecution abstract operation is used by InnerModuleEvaluation to initialize the execution context of the module and evaluate the module's code within it.

From c63435980ccbf3157c181e3db970f607810d82b4 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 7 Jul 2017 19:36:10 -0400 Subject: [PATCH 23/29] Add example STMR graphs section --- img/module-graph-cycle.svg | 63 ++++++++++++++++++++++++++++++++++++ img/module-graph-missing.svg | 48 +++++++++++++++++++++++++++ img/module-graph-simple.svg | 49 ++++++++++++++++++++++++++++ spec.html | 44 +++++++++++++++++++++++-- 4 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 img/module-graph-cycle.svg create mode 100644 img/module-graph-missing.svg create mode 100644 img/module-graph-simple.svg diff --git a/img/module-graph-cycle.svg b/img/module-graph-cycle.svg new file mode 100644 index 0000000000..ecf7d58520 --- /dev/null +++ b/img/module-graph-cycle.svg @@ -0,0 +1,63 @@ + + + + + + + + + + +A + + +B + + +C + + + + + + + + + diff --git a/img/module-graph-missing.svg b/img/module-graph-missing.svg new file mode 100644 index 0000000000..e37d9f7614 --- /dev/null +++ b/img/module-graph-missing.svg @@ -0,0 +1,48 @@ + + + + + + + + + + +A + + +??? + + + + + diff --git a/img/module-graph-simple.svg b/img/module-graph-simple.svg new file mode 100644 index 0000000000..3e68d3df14 --- /dev/null +++ b/img/module-graph-simple.svg @@ -0,0 +1,49 @@ + + + + + + + + + + +A + + +B + + + + + diff --git a/spec.html b/spec.html index 2596ccdc9f..28b69c1e92 100644 --- a/spec.html +++ b/spec.html @@ -21742,7 +21742,7 @@

ModuleDeclarationInstantiation( ) Concrete Method

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

-

ModuleDeclarationInstantiation ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller.

+

ModuleDeclarationInstantiation ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller. In particular, this will cause such failures to propagate to any parent modules in the graph, and thus to their strongly connected components.

This abstract method performs the following steps:

@@ -21859,7 +21859,7 @@

ModuleEvaluation( ) Concrete Method

The ModuleEvaluation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

-

ModuleEvaluation ensures that if evaluation (the actual work for which is performed by InnerModuleEvaluation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller.

+

ModuleEvaluation ensures that if evaluation (the actual work for which is performed by InnerModuleEvaluation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller. In particular, this will cause such failures to propagate to any parent modules in the graph, and thus to their strongly connected components.

This abstract method performs the following steps:

@@ -21945,6 +21945,46 @@

ModuleExecution( _module_ )

+ + +

Example Source Text Module Record Graphs

+ +

This section gives a series of non-normative examples of the instantiation and evaluation of various module graphs, with a specific focus on how errors can occur.

+ +

First consider the following simple module graph:

+ + + A module graph in which module A depends on module B + + +

Let's first assume that there are no error conditions. Then, a host will call _A_.ModuleDeclarationInstantiation(), which will complete successfully by assumption, and recursively instantiate module _B_ as well. This preparatory step can be performed at any time. Later, when the host is ready to incur any possible side effects of the module, it can call _A_.ModuleEvaluation(), which will complete successfully (again by assumption).

+ +

Consider then cases involving instantiation errors. If _B_ cannot be instantiated, for example because it imports itself, then _A_.ModuleDeclarationInstantiation() will fail, and the resulting exception will be recorded in both _A_ and _B_'s [[Status]] and [[ErrorCompletion]] fields. If the host then proceeds to call to _A_.ModuleEvaluation(), the exception will be re-thrown. Storing the exception also ensures that any time a host tries to reuse _A_ or _B_, it will encounter the same exception. (Hosts are not required to reuse Source Text Module Records; similarly, hosts are not required to expose the exception objects thrown by these methods. However, the specification enables such uses.)

+ +

Evaluation errors, such as throwing an exception at top-level, act much the same way as instantiation errors. Like instantiation errors, they are recorded in the [[Status]] and [[ErrorCompletion]] fields, thus preventing future instantiation or evaluation. They differ only in that detection will be delayed until _A_.ModuleEvaluation() is called.

+ +

Note that if the instantiation or evaluation error occurs in _A_, _B_'s [[Status]] and [[ErrorCompletion]] remain unaffected. In other words, there is no propagation of errors to dependencies, only to dependents. (Unless the dependencies are in the same strongly connected component, i.e. are part of a cycle—see below for that case.)

+ +

Now consider a different type of error condition:

+ + + A module graph in which module A depends on a missing (unresolvable) module, represented by ??? + + +

In this scenario, module _A_ declares a dependency (via an `import` statement) on some other module, but no Module Record exists for that module, i.e. HostResolveImportedModule throws an exception when asked for it. This could occur for a variety of reasons, such as the corresponding resource not existing, or the resource existing but ParseModule throwing an exception when trying to parse the resulting source text. Hosts can choose to expose the cause of failure via the exception they throw from HostResolveImportedModule. In any case, this exception causes an instantiation failure, which as before is recorded in _A_.

+ +

Finally consider a module graph with a cycle:

+ + + A module graph in which module A depends on module B and C, but module B also depends on module A + + +

Here we assume that the entry point is module _A_, so that the host proceeds by calling _A_.ModuleDeclarationInstantiation(). This in turn calls _B_.ModuleDeclarationInstantiation(). Because of the cycle, _B_.ModuleDeclarationInstantiation() calls _A_.ModuleDeclarationInstantiation(). In this case, _A_.[[Status]] is `"instantiating"`, so it returns the partially-instantiated _A_. This leaves _B_ as `"instantiating"` as well, i.e. the last steps of InnerModuleDeclarationInstantiation are not performed on _B_. But eventually, when we unwind back up and _C_ has become `"instantiated"`, both _A_ and _B_ then transition from `"instantiating"` to `"instantiated"` together; this is by design, since they are part of the same strongly connected component.

+ +

Now consider a case where _A_ has an instantiation error; for example, it tries to import a binding from _C_ that does not exist. In that case, the above steps still occur, including the early return from the second call to _A_.ModuleDeclarationInstantiation(). However, once we unwind back to the original call to _A_.ModuleDeclarationInstantiation(), it fails during ModuleDeclarationEnvironmentSetup, and in particular during a call to _C_.ResolveExport(). This exception propagates up to ModuleDeclarationInstantiation, which goes through everything in the depth-first search stack and propagates the exception to them. Since the stack at this point consists of both _A_ and _B_, this atomically transitions _A_ and _B_ to the `"errored"` status, as desired. Note that _C_ is left as `"uninstantiated"`.

+ +

Analogous stories occur for evaluation of the cyclic module graph, both in the success and error cases.

+
From a9bc302a5740cbed8af6118a50c7532a319b8599 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 7 Jul 2017 19:39:27 -0400 Subject: [PATCH 24/29] Bonus change: rename ModuleDeclarationInstantiation -> Instantiate, ModuleEvaluation -> Evaluate --- spec.html | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/spec.html b/spec.html index 28b69c1e92..e59a86ce5e 100644 --- a/spec.html +++ b/spec.html @@ -21052,7 +21052,7 @@

Abstract Module Records

@@ -21183,7 +21183,7 @@

Source Text Module Records

Integer | *undefined* @@ -21738,11 +21738,11 @@

Runtime Semantics: PropagateResolution( _module_, _resolution_ )

-

ModuleDeclarationInstantiation( ) Concrete Method

+

Instantiate( ) Concrete Method

-

The ModuleDeclarationInstantiation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

+

The Instantiate concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

-

ModuleDeclarationInstantiation ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller. In particular, this will cause such failures to propagate to any parent modules in the graph, and thus to their strongly connected components.

+

Instantiate ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller. In particular, this will cause such failures to propagate to any parent modules in the graph, and thus to their strongly connected components.

This abstract method performs the following steps:

@@ -21766,14 +21766,14 @@

ModuleDeclarationInstantiation( ) Concrete Method

InnerModuleDeclarationInstantiation( _module_, _stack_, _index_ )

-

The InnerModuleDeclarationInstantiation abstract operation is used by ModuleDeclarationInstantiation to perform the actual instantiation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

+

The InnerModuleDeclarationInstantiation abstract operation is used by Instantiate to perform the actual instantiation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

This abstract operation performs the following steps:

1. If _module_ is not a Source Text Module Record, 1. Assert: _module_.[[Status]] is not `"instantiating"`. - 1. Perform ? _module_.ModuleDeclarationInstantiation(). + 1. Perform ? _module_.Instantiate(). 1. Return _index_. 1. If _module_.[[Status]] is `"instantiating"`, `"instantiated"`, or `"evaluated"`, 1. Return _index_. @@ -21855,11 +21855,11 @@

ModuleDeclarationEnvironmentSetup( _module_ )

-

ModuleEvaluation( ) Concrete Method

+

Evaluate( ) Concrete Method

-

The ModuleEvaluation concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

+

The Evaluate concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

-

ModuleEvaluation ensures that if evaluation (the actual work for which is performed by InnerModuleEvaluation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller. In particular, this will cause such failures to propagate to any parent modules in the graph, and thus to their strongly connected components.

+

Evaluate ensures that if evaluation (the actual work for which is performed by InnerModuleEvaluation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller. In particular, this will cause such failures to propagate to any parent modules in the graph, and thus to their strongly connected components.

This abstract method performs the following steps:

@@ -21883,14 +21883,14 @@

ModuleEvaluation( ) Concrete Method

InnerModuleEvaluation( _module_, _stack_, _index_ )

-

The InnerModuleEvaluation abstract operation is used by ModuleEvaluation to perform the actual evaluation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

+

The InnerModuleEvaluation abstract operation is used by Evaluate to perform the actual evaluation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

This abstract operation performs the following steps:

1. If _module_ is not a Source Text Module Record, 1. Assert: _module_.[[Status]] is not `"evaluating"`. - 1. Perform ? _module_.ModuleEvaluation(). + 1. Perform ? _module_.Evaluate(). 1. Return _index_. 1. If _module_.[[Status]] is `"evaluating"` or `"evaluated"`, 1. Return _index_. @@ -21904,7 +21904,7 @@

InnerModuleEvaluation( _module_, _stack_, _index_ )

1. Append _module_ to _stack_. 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). - 1. NOTE: ModuleDeclarationInstantiation must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. + 1. NOTE: Instantiate must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. 1. Set _index_ to ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_). 1. Assert: _requiredModule_.[[Status]] is either `"evaluating"` or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`evaluating`" if and only if _requiredModule_ is in _stack_. @@ -21957,11 +21957,11 @@

Example Source Text Module Record Graphs

A module graph in which module A depends on module B -

Let's first assume that there are no error conditions. Then, a host will call _A_.ModuleDeclarationInstantiation(), which will complete successfully by assumption, and recursively instantiate module _B_ as well. This preparatory step can be performed at any time. Later, when the host is ready to incur any possible side effects of the module, it can call _A_.ModuleEvaluation(), which will complete successfully (again by assumption).

+

Let's first assume that there are no error conditions. Then, a host will call _A_.Instantiate(), which will complete successfully by assumption, and recursively instantiate module _B_ as well. This preparatory step can be performed at any time. Later, when the host is ready to incur any possible side effects of the module, it can call _A_.Evaluate(), which will complete successfully (again by assumption).

-

Consider then cases involving instantiation errors. If _B_ cannot be instantiated, for example because it imports itself, then _A_.ModuleDeclarationInstantiation() will fail, and the resulting exception will be recorded in both _A_ and _B_'s [[Status]] and [[ErrorCompletion]] fields. If the host then proceeds to call to _A_.ModuleEvaluation(), the exception will be re-thrown. Storing the exception also ensures that any time a host tries to reuse _A_ or _B_, it will encounter the same exception. (Hosts are not required to reuse Source Text Module Records; similarly, hosts are not required to expose the exception objects thrown by these methods. However, the specification enables such uses.)

+

Consider then cases involving instantiation errors. If _B_ cannot be instantiated, for example because it imports itself, then _A_.Instantiate() will fail, and the resulting exception will be recorded in both _A_ and _B_'s [[Status]] and [[ErrorCompletion]] fields. If the host then proceeds to call to _A_.Evaluate(), the exception will be re-thrown. Storing the exception also ensures that any time a host tries to reuse _A_ or _B_, it will encounter the same exception. (Hosts are not required to reuse Source Text Module Records; similarly, hosts are not required to expose the exception objects thrown by these methods. However, the specification enables such uses.)

-

Evaluation errors, such as throwing an exception at top-level, act much the same way as instantiation errors. Like instantiation errors, they are recorded in the [[Status]] and [[ErrorCompletion]] fields, thus preventing future instantiation or evaluation. They differ only in that detection will be delayed until _A_.ModuleEvaluation() is called.

+

Evaluation errors, such as throwing an exception at top-level, act much the same way as instantiation errors. Like instantiation errors, they are recorded in the [[Status]] and [[ErrorCompletion]] fields, thus preventing future instantiation or evaluation. They differ only in that detection will be delayed until _A_.Evaluate() is called.

Note that if the instantiation or evaluation error occurs in _A_, _B_'s [[Status]] and [[ErrorCompletion]] remain unaffected. In other words, there is no propagation of errors to dependencies, only to dependents. (Unless the dependencies are in the same strongly connected component, i.e. are part of a cycle—see below for that case.)

@@ -21979,9 +21979,9 @@

Example Source Text Module Record Graphs

A module graph in which module A depends on module B and C, but module B also depends on module A -

Here we assume that the entry point is module _A_, so that the host proceeds by calling _A_.ModuleDeclarationInstantiation(). This in turn calls _B_.ModuleDeclarationInstantiation(). Because of the cycle, _B_.ModuleDeclarationInstantiation() calls _A_.ModuleDeclarationInstantiation(). In this case, _A_.[[Status]] is `"instantiating"`, so it returns the partially-instantiated _A_. This leaves _B_ as `"instantiating"` as well, i.e. the last steps of InnerModuleDeclarationInstantiation are not performed on _B_. But eventually, when we unwind back up and _C_ has become `"instantiated"`, both _A_ and _B_ then transition from `"instantiating"` to `"instantiated"` together; this is by design, since they are part of the same strongly connected component.

+

Here we assume that the entry point is module _A_, so that the host proceeds by calling _A_.Instantiate(). This in turn calls _B_.Instantiate(). Because of the cycle, _B_.Instantiate() calls _A_.Instantiate(). In this case, _A_.[[Status]] is `"instantiating"`, so it returns the partially-instantiated _A_. This leaves _B_ as `"instantiating"` as well, i.e. the last steps of InnerModuleDeclarationInstantiation are not performed on _B_. But eventually, when we unwind back up and _C_ has become `"instantiated"`, both _A_ and _B_ then transition from `"instantiating"` to `"instantiated"` together; this is by design, since they are part of the same strongly connected component.

-

Now consider a case where _A_ has an instantiation error; for example, it tries to import a binding from _C_ that does not exist. In that case, the above steps still occur, including the early return from the second call to _A_.ModuleDeclarationInstantiation(). However, once we unwind back to the original call to _A_.ModuleDeclarationInstantiation(), it fails during ModuleDeclarationEnvironmentSetup, and in particular during a call to _C_.ResolveExport(). This exception propagates up to ModuleDeclarationInstantiation, which goes through everything in the depth-first search stack and propagates the exception to them. Since the stack at this point consists of both _A_ and _B_, this atomically transitions _A_ and _B_ to the `"errored"` status, as desired. Note that _C_ is left as `"uninstantiated"`.

+

Now consider a case where _A_ has an instantiation error; for example, it tries to import a binding from _C_ that does not exist. In that case, the above steps still occur, including the early return from the second call to _A_.Instantiate(). However, once we unwind back to the original call to _A_.Instantiate(), it fails during ModuleDeclarationEnvironmentSetup, and in particular during a call to _C_.ResolveExport(). This exception propagates up to Instantiate, which goes through everything in the depth-first search stack and propagates the exception to them. Since the stack at this point consists of both _A_ and _B_, this atomically transitions _A_ and _B_ to the `"errored"` status, as desired. Note that _C_ is left as `"uninstantiated"`.

Analogous stories occur for evaluation of the cyclic module graph, both in the success and error cases.

@@ -22042,9 +22042,9 @@

Runtime Semantics: TopLevelModuleEvaluationJob ( _sourceText_, _hostDefined_ 1. If _m_ is a List of errors, then 1. Perform HostReportErrors(_m_). 1. Return NormalCompletion(*undefined*). - 1. Perform ? _m_.ModuleDeclarationInstantiation(). + 1. Perform ? _m_.Instantiate(). 1. Assert: All dependencies of _m_ have been transitively resolved and _m_ is ready for evaluation. - 1. Return ? _m_.ModuleEvaluation(). + 1. Return ? _m_.Evaluate().

An implementation may parse a _sourceText_ as a |Module|, analyse it for Early Error conditions, and instantiate it prior to the execution of the TopLevelModuleEvaluationJob for that _sourceText_. An implementation may also resolve, pre-parse and pre-analyse, and pre-instantiate module dependencies of _sourceText_. However, the reporting of any errors detected by these actions must be deferred until the TopLevelModuleEvaluationJob is actually executed.

From 6f491c4c82a0b84c29f64301caf27c4361054179 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 7 Jul 2017 19:43:22 -0400 Subject: [PATCH 25/29] Typo/style fixes --- spec.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index e59a86ce5e..f8f90f43f9 100644 --- a/spec.html +++ b/spec.html @@ -21700,7 +21700,7 @@

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method @@ -21711,7 +21711,7 @@

Runtime Semantics: ResolutionFailure( _resolveMode_ )

This abstract operation performs the following steps:

- 1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*. + 1. If _resolveMode_ is `"namespace"` or `"star"`, then return *undefined*. 1. Assert: _resolveMode_ is `"normal"`. 1. Throw a new *SyntaxError* exception. From c9b0565bba1b2f250d4692304d6030b02465f76f Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Fri, 21 Jul 2017 16:37:09 +0200 Subject: [PATCH 26/29] Remove ResolveExport's resolveMode argument. Instead, return the blamed module or null. --- spec.html | 115 ++++++++++++++++++++---------------------------------- 1 file changed, 43 insertions(+), 72 deletions(-) diff --git a/spec.html b/spec.html index f8f90f43f9..72bc44d95b 100644 --- a/spec.html +++ b/spec.html @@ -8301,7 +8301,8 @@

[[Get]] ( _P_, _Receiver_ )

1. Let _exports_ be _O_.[[Exports]]. 1. If _P_ is not an element of _exports_, return *undefined*. 1. Let _m_ be _O_.[[Module]]. - 1. Let _binding_ be ! _m_.ResolveExport(_P_, `"normal"`, « »). + 1. Let _binding_ be ! _m_.ResolveExport(_P_, « »). + 1. Assert: _binding_ is a ResolvedBinding Record. 1. Let _targetModule_ be _binding_.[[Module]]. 1. Assert: _targetModule_ is not *undefined*. 1. Let _targetEnv_ be _targetModule_.[[Environment]]. @@ -21043,11 +21044,10 @@

Abstract Module Records

@@ -21639,26 +21639,14 @@

GetExportedNames( _exportStarSet_ ) Concrete Method

-

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method

+

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

The ResolveExport concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter _resolveSet_ is use to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and _exportName_ is reached that is already in _resolveSet_, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of _module_ and _exportName_ is added to _resolveSet_.

-

If a defining module is found, a ResolvedBinding Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export. If no definition is found or the request is found to be circular or ambiguous, an error is thrown or *undefined* is returned, depending on _resolveMode_ (see below for more details).

- -

In addition to the standard _resolveMode_ values of `"normal"` or `"namespace"`, ResolveExport for Source Text Module Records also accepts a third value, `"star"`. This is only used when it calls itself recursively, in order to help implement the semantics of the `"normal"` mode.

- -

Its failure behavior, when the _exportName_ cannot be resolved, varies among the different _resolveMode_ values:

-
-
`"normal"`
-
Throws a *SyntaxError* exception, which is recorded in the culprit module when applicable.
- -
`"namespace"`
-
Returns *undefined*.
- -
`"star"`
-
If a culprit module responsible for the unresolved name can be found, and has a recorded exception, it is rethrown. Otherwise, returns *undefined*.
-
+

If a defining module is found, a ResolvedBinding Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export.

+ +

If no definition is found or the request is detected to be circular or ambiguous and the resolution attempt yielded a culprit module record, then this module record is returned. If no culprit was found, *null* is returned instead. TODO: give examples.

(Note that if HostResolveImportedModule throws, the above analysis does not apply; such errors will be rethrown before any mode-specific logic is involved.)

@@ -21670,7 +21658,7 @@

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method - - -

Runtime Semantics: ResolutionFailure( _resolveMode_ )

- -

The ResolutionFailure abstract operation is used by ResolveExport to react property to a module resolution failure in a given _resolveMode_.

- -

This abstract operation performs the following steps:

- - 1. If _resolveMode_ is `"namespace"` or `"star"`, then return *undefined*. - 1. Assert: _resolveMode_ is `"normal"`. - 1. Throw a new *SyntaxError* exception. - -
- - -

Runtime Semantics: PropagateResolution( _module_, _resolution_ )

- -

The PropagateResolution abstract operation is used by ResolveExport to ensure any module resolution failures from indirect or star exports are correctly propagated to the Source Text Module Record in question.

- -

This abstract operation performs the following steps:

- - 1. If _resolution_ is an abrupt completion, then - 1. If _module_.[[Status]] is `"errored"`, then - 1. Assert: _module_.[[ErrorCompletion]] is _resolution_. - 1. Otherwise, - 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. - 1. Set _module_.[[Status]] to `"errored"`. - 1. Set _module_.[[ErrorCompletion]] to _resolution_. - 1. Return _resolution_. - -
@@ -21812,7 +21766,9 @@

ModuleDeclarationEnvironmentSetup( _module_ )

1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do - 1. Perform ? _module_.ResolveExport(_e_.[[ExportName]], `"normal"`, « »). + 1. Let _resolution_ be ? _module_.ResolveExport(_e_.[[ExportName]], « »). + 1. Assert: _resolution_ is not *null*. + 1. If _resolution_ is a Module Record (i.e., not a ResolvedBinding Record), return ResolutionError(_resolution_). 1. Assert: All named exports from _module_ are resolvable. 1. Let _realm_ be _module_.[[Realm]]. 1. Assert: _realm_ is not *undefined*. @@ -21827,8 +21783,9 @@

ModuleDeclarationEnvironmentSetup( _module_ )

1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). 1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, - 1. Let _resolution_ be _importedModule_.ResolveExport(_in_.[[ImportName]], `"normal"`, « »). - 1. Perform ? PropagateResolution(_module_, _resolution_). + 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], « »). + 1. If _resolution_ is *null*, let _resolution_ be _module_. + 1. If _resolution_ is a Module Record, return ResolutionError(_resolution_). 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). 1. Let _code_ be _module_.[[ECMAScriptCode]]. 1. Let _varDeclarations_ be the VarScopedDeclarations of _code_. @@ -21851,6 +21808,20 @@

ModuleDeclarationEnvironmentSetup( _module_ )

1. Call _envRec_.InitializeBinding(_dn_, _fo_).
+ + +

ResolutionError( _module_ )

+ +

The ResolutionError abstract operation is used by ModuleDeclarationEnvironmentSetup to record and return an import/export resolution error. It performs the following steps:

+ + + 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. + 1. Set _module_.[[Status]] to `"errored"`. + 1. Let _completion_ be Completion{[[Type]]: ~throw~, [[Value]]: a newly created *SyntaxError* object, [[Target]]: ~empty~}. + 1. Set _module_.[[ErrorCompletion]] to _completion_. + 1. Return _completion_. + +
@@ -22021,8 +21992,8 @@

Runtime Semantics: GetModuleNamespace( _module_ )

1. Let _exportedNames_ be ? _module_.GetExportedNames(« »). 1. Let _unambiguousNames_ be a new empty List. 1. For each _name_ that is an element of _exportedNames_, do - 1. Let _resolution_ be ? _module_.ResolveExport(_name_, `"namespace"`, « »). - 1. If _resolution_ is not *undefined*, append _name_ to _unambiguousNames_. + 1. Let _resolution_ be ? _module_.ResolveExport(_name_, « »). + 1. If _resolution_ is a ResolvedBinding Record, append _name_ to _unambiguousNames_. 1. Set _namespace_ to ModuleNamespaceCreate(_module_, _unambiguousNames_). 1. Return _namespace_. From f19fcde71bdbe24ad181a873d03ca8d6076e76f5 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Mon, 24 Jul 2017 14:01:25 +0200 Subject: [PATCH 27/29] Revise various explanations of module operations and examples. --- img/module-graph-simple.svg | 21 ++++++++++++++------- spec.html | 22 ++++++++++------------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/img/module-graph-simple.svg b/img/module-graph-simple.svg index 3e68d3df14..6481b56089 100644 --- a/img/module-graph-simple.svg +++ b/img/module-graph-simple.svg @@ -1,4 +1,4 @@ - +

Abstract Module Records

Instantiate()
@@ -21696,7 +21696,7 @@

Instantiate( ) Concrete Method

The Instantiate concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

-

Instantiate ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in the module's [[Status]] and [[ErrorCompletion]] fields, and furthermore this failure is propagated to every other module in the same strongly connected component of the module graph. The exception that caused the failure is then re-thrown to the caller. In particular, this will cause such failures to propagate to any parent modules in the graph, and thus to their strongly connected components.

+

Instantiate ensures that if instantiation (the actual work for which is performed by InnerModuleDeclarationInstantiation) fails, that fact is recorded in this module's [[Status]] and [[ErrorCompletion]] fields. If the error is blamed on a dependent module, it is additionally recorded there in the same way.

This abstract method performs the following steps:

@@ -21720,7 +21720,7 @@

Instantiate( ) Concrete Method

InnerModuleDeclarationInstantiation( _module_, _stack_, _index_ )

-

The InnerModuleDeclarationInstantiation abstract operation is used by Instantiate to perform the actual instantiation process for the Source Text Module Record _module_, as well as recursively on all other modules in the same strongly connected component of the module graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used to track the traversal within the strongly connected component.

+

The InnerModuleDeclarationInstantiation abstract operation is used by Instantiate to perform the actual instantiation process for the Source Text Module Record _module_, as well as recursively on all other Source Text Module Records in the dependency graph. The _stack_ and _index_ parameters, as well as a module's [[DFSIndex]] and [[DFSAncestorIndex]] fields, keep track of the depth-first search (DFS) traversal. In particular, [[DFSAncestorIndex]] is used to discover strongly connected components (SCCs), such that all modules in an SCC transition to `"instantiated"` together.

This abstract operation performs the following steps:

@@ -21920,29 +21920,27 @@

ModuleExecution( _module_ )

Example Source Text Module Record Graphs

-

This section gives a series of non-normative examples of the instantiation and evaluation of various module graphs, with a specific focus on how errors can occur.

+

This non-normative section gives a series of examples of the instantiation and evaluation of a few common module graphs, with a specific focus on how errors can occur.

First consider the following simple module graph:

- A module graph in which module A depends on module B + A module graph in which module A depends on module B -

Let's first assume that there are no error conditions. Then, a host will call _A_.Instantiate(), which will complete successfully by assumption, and recursively instantiate module _B_ as well. This preparatory step can be performed at any time. Later, when the host is ready to incur any possible side effects of the module, it can call _A_.Evaluate(), which will complete successfully (again by assumption).

+

Let's first assume that there are no error conditions. When a host first calls _A_.Instantiate(), this will complete successfully by assumption, and recursively instantiate modules _B_ and _C_ as well, such that _A_.[[Status]] = _B_.[[Status]] = _C_.[[Status]] = `"instantiated"`. This preparatory step can be performed at any time. Later, when the host is ready to incur any possible side effects of the modules, it can call _A_.Evaluate(), which will complete successfully (again by assumption), recursively having evaluated first _C_ and then _B_. Each module's [[Status]] at this point will be `"evaluated`".

-

Consider then cases involving instantiation errors. If _B_ cannot be instantiated, for example because it imports itself, then _A_.Instantiate() will fail, and the resulting exception will be recorded in both _A_ and _B_'s [[Status]] and [[ErrorCompletion]] fields. If the host then proceeds to call to _A_.Evaluate(), the exception will be re-thrown. Storing the exception also ensures that any time a host tries to reuse _A_ or _B_, it will encounter the same exception. (Hosts are not required to reuse Source Text Module Records; similarly, hosts are not required to expose the exception objects thrown by these methods. However, the specification enables such uses.)

+

Consider then cases involving instantiation errors. If InnerModuleDeclarationInstantiation of _C_ succeeds but, thereafter, fails for _B_, for example because it imports something that _C_ does not provide, then the original _A_.Instantiate() will fail, and the resulting exception will be recorded in both _A_ and _B_'s [[Status]] and [[ErrorCompletion]] fields (_C_ will remain `"instantiated"`). If the host then proceeds to call to _A_.Evaluate(), the exception will be re-thrown. Storing the exception also ensures that any time a host tries to reuse _A_ or _B_, it will encounter the same exception. (Hosts are not required to reuse Source Text Module Records; similarly, hosts are not required to expose the exception objects thrown by these methods. However, the specification enables such uses.)

Evaluation errors, such as throwing an exception at top-level, act much the same way as instantiation errors. Like instantiation errors, they are recorded in the [[Status]] and [[ErrorCompletion]] fields, thus preventing future instantiation or evaluation. They differ only in that detection will be delayed until _A_.Evaluate() is called.

-

Note that if the instantiation or evaluation error occurs in _A_, _B_'s [[Status]] and [[ErrorCompletion]] remain unaffected. In other words, there is no propagation of errors to dependencies, only to dependents. (Unless the dependencies are in the same strongly connected component, i.e. are part of a cycle—see below for that case.)

-

Now consider a different type of error condition:

A module graph in which module A depends on a missing (unresolvable) module, represented by ??? -

In this scenario, module _A_ declares a dependency (via an `import` statement) on some other module, but no Module Record exists for that module, i.e. HostResolveImportedModule throws an exception when asked for it. This could occur for a variety of reasons, such as the corresponding resource not existing, or the resource existing but ParseModule throwing an exception when trying to parse the resulting source text. Hosts can choose to expose the cause of failure via the exception they throw from HostResolveImportedModule. In any case, this exception causes an instantiation failure, which as before is recorded in _A_.

+

In this scenario, module _A_ declares a dependency on some other module, but no Module Record exists for that module, i.e. HostResolveImportedModule throws an exception when asked for it. This could occur for a variety of reasons, such as the corresponding resource not existing, or the resource existing but ParseModule throwing an exception when trying to parse the resulting source text. Hosts can choose to expose the cause of failure via the exception they throw from HostResolveImportedModule. In any case, this exception causes an instantiation failure, which as before is recorded in _A_.

Finally consider a module graph with a cycle:

@@ -21950,9 +21948,9 @@

Example Source Text Module Record Graphs

A module graph in which module A depends on module B and C, but module B also depends on module A -

Here we assume that the entry point is module _A_, so that the host proceeds by calling _A_.Instantiate(). This in turn calls _B_.Instantiate(). Because of the cycle, _B_.Instantiate() calls _A_.Instantiate(). In this case, _A_.[[Status]] is `"instantiating"`, so it returns the partially-instantiated _A_. This leaves _B_ as `"instantiating"` as well, i.e. the last steps of InnerModuleDeclarationInstantiation are not performed on _B_. But eventually, when we unwind back up and _C_ has become `"instantiated"`, both _A_ and _B_ then transition from `"instantiating"` to `"instantiated"` together; this is by design, since they are part of the same strongly connected component.

+

Here we assume that the entry point is module _A_, so that the host proceeds by calling _A_.Instantiate(), which performs InnerModuleDeclarationInstantiation on _A_. This in turn calls InnerModuleDeclarationInstantiation on _B_. Because of the cycle, this again triggers InnerModuleDeclarationInstantiation on _A_, but at this point it is a no-op since _A_.[[Status]] is already `"instantiating"`. _B_.[[Status]] itself remains `"instantiating"` when control gets back to _A_ and InnerModuleDeclarationInstantiation is triggered on _C_. After this returns with _C_.[[Status]] being `"instantiated"` , both _A_ and _B_ transition from `"instantiating"` to `"instantiated"` together; this is by design, since they form a strongly connected component.

-

Now consider a case where _A_ has an instantiation error; for example, it tries to import a binding from _C_ that does not exist. In that case, the above steps still occur, including the early return from the second call to _A_.Instantiate(). However, once we unwind back to the original call to _A_.Instantiate(), it fails during ModuleDeclarationEnvironmentSetup, and in particular during a call to _C_.ResolveExport(). This exception propagates up to Instantiate, which goes through everything in the depth-first search stack and propagates the exception to them. Since the stack at this point consists of both _A_ and _B_, this atomically transitions _A_ and _B_ to the `"errored"` status, as desired. Note that _C_ is left as `"uninstantiated"`.

+

Now consider a case where _A_ has an instantiation error; for example, it tries to import a binding from _C_ that does not exist. In that case, the above steps still occur, including the early return from the second call to InnerModuleDeclarationInstantiation on _A_. However, once we unwind back to the original InnerModuleDeclarationInstantiation on _A_, it fails during ModuleDeclarationEnvironmentSetup, namely in _C_.ResolveExport(). The exception thrown by ResolutionError propagates up to _A_.Instantiate, which records the error in all modules that are currently on its _stack_ (these are always exactly the modules that are still `"instantiating"`). Hence both _A_ and _B_ become `"errored"`. Note that _C_ is left as `"instantiated"`.

Analogous stories occur for evaluation of the cyclic module graph, both in the success and error cases.

From b899bb720c1bfbc0402cff8a8c1de1352d4f4d9a Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Wed, 26 Jul 2017 17:11:04 -0700 Subject: [PATCH 28/29] Consistify diagram module names --- img/module-graph-simple.svg | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/img/module-graph-simple.svg b/img/module-graph-simple.svg index 6481b56089..055ad7a660 100644 --- a/img/module-graph-simple.svg +++ b/img/module-graph-simple.svg @@ -26,13 +26,13 @@ -a.js +A -b.js +B -c.js +C @@ -40,16 +40,16 @@ From 152c344fb99b8b1565ebf155dc5ac592f5d407d9 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Thu, 27 Jul 2017 14:49:19 +0200 Subject: [PATCH 29/29] Preserve behavior concerning ambiguous export errors. --- spec.html | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/spec.html b/spec.html index abe1b54132..048b8b40f9 100644 --- a/spec.html +++ b/spec.html @@ -21047,7 +21047,7 @@

Abstract Module Records

ResolveExport(_exportName_, _resolveSet_)
@@ -21646,9 +21646,15 @@

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

If a defining module is found, a ResolvedBinding Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export.

-

If no definition is found or the request is detected to be circular or ambiguous and the resolution attempt yielded a culprit module record, then this module record is returned. If no culprit was found, *null* is returned instead. TODO: give examples.

+

If a defining module cannot be found (i.e. resolution fails), there are three cases. +

    +
  • The resolution failure can be blamed on a particular module. Then this culprit module record is returned.
  • +
  • No culprit can be determined and the resolution failure was due to star export ambiguity. Then `"ambiguous"` is returned.
  • +
  • No culprit can be determined and the resolution failure was not due to star export ambiguity. Then *null* is returned.
  • +
+

-

(Note that if HostResolveImportedModule throws, the above analysis does not apply; such errors will be rethrown before any mode-specific logic is involved.)

+

(Note that if HostResolveImportedModule throws, the above analysis does not apply; such errors will be propagated immediately.)

This abstract method performs the following steps:

@@ -21669,7 +21675,7 @@

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

1. Assert: _module_ imports a specific binding for this export. 1. Let _importedModule_ be ? HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). 1. Let _resolution_ be ? _importedModule_.ResolveExport(_e_.[[ImportName]], _resolveSet_). - 1. If _resolution_ is *null*, let _resolution_ be _module_. + 1. If _resolution_ is *null* or `"ambiguous"`, let _resolution_ be _module_. 1. Return _resolution_. 1. If SameValue(_exportName_, `"default"`) is *true*, then 1. Assert: A `default` export was not explicitly defined by this module. @@ -21679,13 +21685,13 @@

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

1. For each ExportEntry Record _e_ in _module_.[[StarExportEntries]], do 1. Let _importedModule_ be ? HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). 1. Let _resolution_ be ? _importedModule_.ResolveExport(_exportName_, _resolveSet_). - 1. If _resolution_ is a Module Record, return _resolution_. + 1. If _resolution_ is `"ambiguous"` or a Module Record, return _resolution_. 1. If _resolution_ is not *null*, then 1. Assert: _resolution_ is a ResolvedBinding Record. 1. If _starResolution_ is *null*, set _starResolution_ to _resolution_. 1. Else, 1. Assert: There is more than one `*` import that includes the requested name. - 1. If _resolution_.[[Module]] and _starResolution_.[[Module]] are not the same Module Record or SameValue(_resolution_.[[BindingName]], _starResolution_.[[BindingName]]) is *false*, return _module_. + 1. If _resolution_.[[Module]] and _starResolution_.[[Module]] are not the same Module Record or SameValue(_resolution_.[[BindingName]], _starResolution_.[[BindingName]]) is *false*, return `"ambiguous"`. 1. Return _starResolution_. @@ -21767,8 +21773,9 @@

ModuleDeclarationEnvironmentSetup( _module_ )

1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do 1. Let _resolution_ be ? _module_.ResolveExport(_e_.[[ExportName]], « »). - 1. Assert: _resolution_ is not *null*. - 1. If _resolution_ is a Module Record (i.e., not a ResolvedBinding Record), return ResolutionError(_resolution_). + 1. Assert: _resolution_ is neither *null* nor `"ambiguous"`. + 1. If _resolution_ is a Module Record, return ResolutionError(_resolution_). + 1. Assert: _resolution_ is a ResolvedBinding Record. 1. Assert: All named exports from _module_ are resolvable. 1. Let _realm_ be _module_.[[Realm]]. 1. Assert: _realm_ is not *undefined*. @@ -21784,7 +21791,7 @@

ModuleDeclarationEnvironmentSetup( _module_ )

1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], « »). - 1. If _resolution_ is *null*, let _resolution_ be _module_. + 1. If _resolution_ is *null* or `"ambiguous"`, let _resolution_ be _module_. 1. If _resolution_ is a Module Record, return ResolutionError(_resolution_). 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). 1. Let _code_ be _module_.[[ECMAScriptCode]].
- ResolveExport(exportName, resolveSet) + ResolveExport(exportName, resolveMode, resolveSet) Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: Module Record, [[BindingName]]: String}. Return *null* if the name cannot be resolved, or `"ambiguous"` if multiple bindings were found. @@ -21638,16 +21637,30 @@

GetExportedNames( _exportStarSet_ ) Concrete Method

+ +

Runtime Semantics: ResolutionFailure( _module_, _resolveMode_ )

+

The ResolutionFailure abstract operation performs the following steps:

+ + 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. + 1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*. + 1. Assert: _resolveMode_ is `"default"`. + 1. Let _error_ be Completion{[[Type]]: ~throw~, [[Value]]: a newly created *SyntaxError* object, [[Target]]: ~empty~}. + 1. Set _module_.[[ErrorCompletion]] to _error_. + 1. Set _module_.[[Status]] to `"errored"`. + 1. Return _error_. + +
+ -

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

-

The ResolveExport concrete method of a Source Text Module Record with arguments _exportName_, and _resolveSet_ performs the following steps:

+

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method

+

The ResolveExport concrete method of a Source Text Module Record with arguments _exportName_, _resolveMode_, and _resolveSet_ performs the following steps:

1. Let _module_ be this Source Text Module Record. 1. For each Record {[[Module]], [[ExportName]]} _r_ in _resolveSet_, do 1. If _module_ and _r_.[[Module]] are the same Module Record and SameValue(_exportName_, _r_.[[ExportName]]) is *true*, then 1. Assert: This is a circular import request. - 1. Return *null*. + 1. Return _ResolutionFailure_(_module_, _resolveMode_). 1. Append the Record {[[Module]]: _module_, [[ExportName]]: _exportName_} to _resolveSet_. 1. For each ExportEntry Record _e_ in _module_.[[LocalExportEntries]], do 1. If SameValue(_exportName_, _e_.[[ExportName]]) is *true*, then @@ -21657,22 +21670,29 @@

ResolveExport( _exportName_, _resolveSet_ ) Concrete Method

1. If SameValue(_exportName_, _e_.[[ExportName]]) is *true*, then 1. Assert: _module_ imports a specific binding for this export. 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). - 1. Return ? _importedModule_.ResolveExport(_e_.[[ImportName]], _resolveSet_). + 1. If _resolveMode_ is `"star"`, set _resolveMode_ to `"default"`. + 1. Return _importedModule_.ResolveExport(_e_.[[ImportName]], _resolveMode_, _resolveSet_). 1. If SameValue(_exportName_, `"default"`) is *true*, then 1. Assert: A `default` export was not explicitly defined by this module. - 1. Return *null*. + 1. Return _ResolutionFailure_(_module_, _resolveMode_). 1. NOTE: A `default` export cannot be provided by an `export *`. - 1. Let _starResolution_ be *null*. + 1. Let _starResolution_ be *undefined*. + 1. Let _newResolveMode_ be _resolveMode_. + 1. If _resolveMode_ is `"default"`, set _newResolveMode_ to `"star"`. 1. For each ExportEntry Record _e_ in _module_.[[StarExportEntries]], do 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). - 1. Let _resolution_ be ? _importedModule_.ResolveExport(_exportName_, _resolveSet_). - 1. If _resolution_ is `"ambiguous"`, return `"ambiguous"`. - 1. If _resolution_ is not *null*, then + 1. Let _resolution_ be ? _importedModule_.ResolveExport(_exportName_, _newResolveMode_, _resolveSet_). + 1. If _resolution_ is not *undefined*, then 1. If _starResolution_ is *null*, set _starResolution_ to _resolution_. 1. Else, 1. Assert: There is more than one `*` import that includes the requested name. - 1. If _resolution_.[[Module]] and _starResolution_.[[Module]] are not the same Module Record or SameValue(_resolution_.[[BindingName]], _starResolution_.[[BindingName]]) is *false*, return `"ambiguous"`. - 1. Return _starResolution_. + 1. If _resolveMode_ is `"star"`, set _resolveMode_ to `"default"`. + 1. If _resolution_.[[Module]] and _starResolution_.[[Module]] + are not the same Module Record or + SameValue(_resolution_.[[BindingName]], + _starResolution_.[[BindingName]]) is *false*, return _ResolutionFailure_(_module_, _resolveMode_). + 1. If _starResolution_ is *undefined*, return _ResolutionFailure_(_module_, _resolveMode_); + 1. Otherwise, return _starResolution_.

ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter _resolveSet_ is use to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and _exportName_ is reached that is already in _resolveSet_, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of _module_ and _exportName_ is added to _resolveSet_.

@@ -21691,7 +21711,7 @@

ModuleDeclarationInstantiation( ) Concrete Method

1. Let _result_ be InnerModuleDeclarationInstantiation(_module_, _stack_, 0). 1. If _result_ is an abrupt completion, 1. For each module _m_ in _stack_, - 1. Assert: _m_.[[Status]] is `"instantiating"`. + 1. Assert: _m_.[[Status]] is `"instantiating"` or `"errored"`. 1. Set _m_.[[Status]] to `"errored"`. 1. Set _m_.[[ErrorCompletion]] to _result_. 1. Assert: _module_.[[Status]] is `"errored"` and _module_.[[ErrorCompletion]] is _result_. @@ -21740,8 +21760,7 @@

Runtime Semantics: ModuleDeclarationResolution( _module_ )

The ModuleDeclarationResolution abstract operation performs the following steps:

1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do - 1. Let _resolution_ be ? _module_.ResolveExport(_e_.[[ExportName]], « »). - 1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception. + 1. Perform ? _module_.ResolveExport(_e_.[[ExportName]], `"default"`, « »). 1. Assert: All named exports from _module_ are resolvable. 1. Let _realm_ be _module_.[[Realm]]. 1. Assert: _realm_ is not *undefined*. @@ -21754,12 +21773,11 @@

Runtime Semantics: ModuleDeclarationResolution( _module_ )

requests are a subset of _module_.[[RequestedModules]], and these have been resolved earlier in this algorithm. --> 1. If _in_.[[ImportName]] is `"*"`, then - 1. Let _namespace_ be ? GetModuleNamespace(_importedModule_). + 1. Let _namespace_ be ! GetModuleNamespace(_importedModule_). 1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). 1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, - 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], « »). - 1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception. + 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], `"default"`, « »). 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). 1. Let _code_ be _module_.[[ECMAScriptCode]]. 1. Let _varDeclarations_ be the VarScopedDeclarations of _code_. @@ -21893,9 +21911,8 @@

Runtime Semantics: GetModuleNamespace( _module_ )

1. Let _exportedNames_ be ! _module_.GetExportedNames(« »). 1. Let _unambiguousNames_ be a new empty List. 1. For each _name_ that is an element of _exportedNames_, do - 1. Let _resolution_ be ? _module_.ResolveExport(_name_, « »). - 1. If _resolution_ is *null*, throw a *SyntaxError* exception. - 1. If _resolution_ is not `"ambiguous"`, append _name_ to _unambiguousNames_. + 1. Let _resolution_ be ! _module_.ResolveExport(_name_, `"namespace"`, « »). + 1. If _resolution_ is not *undefined*, append _name_ to _unambiguousNames_. 1. Set _namespace_ to ModuleNamespaceCreate(_module_, _unambiguousNames_). 1. Return _namespace_.
From ccc15d50b369445c775adaa50286d7f3b058d64f Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Mon, 19 Jun 2017 14:14:40 -0400 Subject: [PATCH 10/29] Fix editorial issues --- spec.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec.html b/spec.html index a078e81897..8e749507c2 100644 --- a/spec.html +++ b/spec.html @@ -21660,7 +21660,7 @@

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method From 0cbc172bd08f733d57709404d04eb5e8089b20a0 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Tue, 20 Jun 2017 11:08:29 +0200 Subject: [PATCH 11/29] Revert "Assume HostResolveImportedModule never fails." This reverts commit 59d782a12aa17ac29aa691591c6fc5c287396b6f. --- spec.html | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/spec.html b/spec.html index 8e749507c2..dd40b58abf 100644 --- a/spec.html +++ b/spec.html @@ -21624,8 +21624,8 @@

GetExportedNames( _exportStarSet_ ) Concrete Method

1. Assert: _module_ imports a specific binding for this export. 1. Append _e_.[[ExportName]] to _exportedNames_. 1. For each ExportEntry Record _e_ in _module_.[[StarExportEntries]], do - 1. Let _requestedModule_ be ! HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). - 1. Let _starNames_ be ! _requestedModule_.GetExportedNames(_exportStarSet_). + 1. Let _requestedModule_ be ? HostResolveImportedModule(_module_, _e_.[[ModuleRequest]]). + 1. Let _starNames_ be ? _requestedModule_.GetExportedNames(_exportStarSet_). 1. For each element _n_ of _starNames_, do 1. If SameValue(_n_, `"default"`) is *false*, then 1. If _n_ is not an element of _exportedNames_, then @@ -21669,7 +21669,7 @@

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodRuntime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ 1. Set _module_.[[DFSAncestorIndex]] to _index_. 1. Append _module_ to _stack_. 1. For each String _required_ that is an element of _module_.[[RequestedModules]], - 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). + 1. Let _requiredModule_ be ? HostResolveImportedModule(_module_, _required_). 1. Perform ? InnerModuleDeclarationInstantiation(_requiredModule_, _stack_, _index_+1). 1. Assert: _requiredModule_.[[Status]] is either `"instantiating"`, `"instantiated"`, or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`instantiating`" if and only if _requiredModule_ is in _stack_. @@ -21769,9 +21769,7 @@

Runtime Semantics: ModuleDeclarationResolution( _module_ )

1. Let _envRec_ be _env_'s EnvironmentRecord. 1. For each ImportEntry Record _in_ in _module_.[[ImportEntries]], do 1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _in_.[[ModuleRequest]]). - + 1. NOTE: The above call cannot fail because imported module requests are a subset of _module_.[[RequestedModules]], and these have been resolved earlier in this algorithm. 1. If _in_.[[ImportName]] is `"*"`, then 1. Let _namespace_ be ! GetModuleNamespace(_importedModule_). 1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). @@ -21908,7 +21906,7 @@

Runtime Semantics: GetModuleNamespace( _module_ )

1. Assert: _module_.[[Status]] is neither `"uninstantiated"` nor `"errored"`. 1. Let _namespace_ be _module_.[[Namespace]]. 1. If _namespace_ is *undefined*, then - 1. Let _exportedNames_ be ! _module_.GetExportedNames(« »). + 1. Let _exportedNames_ be ? _module_.GetExportedNames(« »). 1. Let _unambiguousNames_ be a new empty List. 1. For each _name_ that is an element of _exportedNames_, do 1. Let _resolution_ be ! _module_.ResolveExport(_name_, `"namespace"`, « »). From 161fae3bc02d547e883a4cc7cad41727aab3b753 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Tue, 20 Jun 2017 11:16:39 +0200 Subject: [PATCH 12/29] Rename resolve mode "default" to "normal". --- spec.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec.html b/spec.html index dd40b58abf..5a2b8e82ad 100644 --- a/spec.html +++ b/spec.html @@ -8301,7 +8301,7 @@

[[Get]] ( _P_, _Receiver_ )

1. Let _exports_ be _O_.[[Exports]]. 1. If _P_ is not an element of _exports_, return *undefined*. 1. Let _m_ be _O_.[[Module]]. - 1. Let _binding_ be ! _m_.ResolveExport(_P_, `"default"`, « »). + 1. Let _binding_ be ! _m_.ResolveExport(_P_, `"normal"`, « »). 1. Let _targetModule_ be _binding_.[[Module]]. 1. Assert: _targetModule_ is not *undefined*. 1. Let _targetEnv_ be _targetModule_.[[Environment]]. @@ -21643,7 +21643,7 @@

Runtime Semantics: ResolutionFailure( _module_, _resolveMode_ )

1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. 1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*. - 1. Assert: _resolveMode_ is `"default"`. + 1. Assert: _resolveMode_ is `"normal"`. 1. Let _error_ be Completion{[[Type]]: ~throw~, [[Value]]: a newly created *SyntaxError* object, [[Target]]: ~empty~}. 1. Set _module_.[[ErrorCompletion]] to _error_. 1. Set _module_.[[Status]] to `"errored"`. @@ -21670,7 +21670,7 @@

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodRuntime Semantics: ModuleDeclarationResolution( _module_ )

The ModuleDeclarationResolution abstract operation performs the following steps:

1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do - 1. Perform ? _module_.ResolveExport(_e_.[[ExportName]], `"default"`, « »). + 1. Perform ? _module_.ResolveExport(_e_.[[ExportName]], `"normal"`, « »). 1. Assert: All named exports from _module_ are resolvable. 1. Let _realm_ be _module_.[[Realm]]. 1. Assert: _realm_ is not *undefined*. @@ -21775,7 +21775,7 @@

Runtime Semantics: ModuleDeclarationResolution( _module_ )

1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). 1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, - 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], `"default"`, « »). + 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], `"normal"`, « »). 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). 1. Let _code_ be _module_.[[ECMAScriptCode]]. 1. Let _varDeclarations_ be the VarScopedDeclarations of _code_. From ceee6fea60e1e53592be0543c5d9dbdcd3a74a11 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Tue, 20 Jun 2017 11:56:49 +0200 Subject: [PATCH 13/29] Add two invariants. --- spec.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 5a2b8e82ad..04265b7186 100644 --- a/spec.html +++ b/spec.html @@ -21657,6 +21657,7 @@

ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodThe ResolveExport concrete method of a Source Text Module Record with arguments _exportName_, _resolveMode_, and _resolveSet_ performs the following steps:

1. Let _module_ be this Source Text Module Record. + 1. Assert: _module_.[[Status]] is not `"errored"`. 1. For each Record {[[Module]], [[ExportName]]} _r_ in _resolveSet_, do 1. If _module_ and _r_.[[Module]] are the same Module Record and SameValue(_exportName_, _r_.[[ExportName]]) is *true*, then 1. Assert: This is a circular import request. @@ -21885,7 +21886,7 @@

Runtime Semantics: HostResolveImportedModule ( _referencingModule_, _specifi

The implementation of HostResolveImportedModule must conform to the following requirements:

  • - The normal return value must be an instance of a concrete subclass of Module Record. + The normal return value must be an instance of a concrete subclass of Module Record, and its [[Status]] must not be `"errored"`.
  • If a Module Record corresponding to the pair _referencingModule_, _specifier_ does not exist or cannot be created, an exception must be thrown. From 95ca7e6f72de2b896e26ecb1dff5d1439745db00 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Tue, 20 Jun 2017 12:51:10 +0200 Subject: [PATCH 14/29] Account for exception in caller of ResolveExport... ...now that we allow the callback to throw again. Also add a comment on GetModuleNamespace. --- spec.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 04265b7186..cb92232dae 100644 --- a/spec.html +++ b/spec.html @@ -21772,7 +21772,7 @@

    Runtime Semantics: ModuleDeclarationResolution( _module_ )

    1. Let _importedModule_ be ! HostResolveImportedModule(_module_, _in_.[[ModuleRequest]]). 1. NOTE: The above call cannot fail because imported module requests are a subset of _module_.[[RequestedModules]], and these have been resolved earlier in this algorithm. 1. If _in_.[[ImportName]] is `"*"`, then - 1. Let _namespace_ be ! GetModuleNamespace(_importedModule_). + 1. Let _namespace_ be ? GetModuleNamespace(_importedModule_). 1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). 1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, @@ -21910,11 +21910,14 @@

    Runtime Semantics: GetModuleNamespace( _module_ )

    1. Let _exportedNames_ be ? _module_.GetExportedNames(« »). 1. Let _unambiguousNames_ be a new empty List. 1. For each _name_ that is an element of _exportedNames_, do - 1. Let _resolution_ be ! _module_.ResolveExport(_name_, `"namespace"`, « »). + 1. Let _resolution_ be ? _module_.ResolveExport(_name_, `"namespace"`, « »). 1. If _resolution_ is not *undefined*, append _name_ to _unambiguousNames_. 1. Set _namespace_ to ModuleNamespaceCreate(_module_, _unambiguousNames_). 1. Return _namespace_. + +

    The only way GetModuleNamespace can throw is via one of the triggered HostResolveImportedModule calls.

    +
    From 01942162fb9384dca2d592767f96ad9fe9c27bdf Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Tue, 20 Jun 2017 12:59:42 +0200 Subject: [PATCH 15/29] Update note on ResolveExport. --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index cb92232dae..552c29fe60 100644 --- a/spec.html +++ b/spec.html @@ -21697,7 +21697,7 @@

    ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method

    ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter _resolveSet_ is use to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and _exportName_ is reached that is already in _resolveSet_, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of _module_ and _exportName_ is added to _resolveSet_.

    -

    If a defining module is found, a ResolvedBinding Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export. If no definition was found or the request is found to be circular, *null* is returned. If the request is found to be ambiguous, the string `"ambiguous"` is returned.

    +

    If a defining module is found, a ResolvedBinding Record {[[Module]], [[BindingName]]} is returned. This record identifies the resolved binding of the originally requested export. If no definition is found or the request is found to be circular or ambiguous, an error is thrown or *undefined* is returned, depending on _resolveMode_.

    From 87742a57eb63e0cfda1190cd0d00f56c9c085332 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Tue, 20 Jun 2017 13:12:37 +0200 Subject: [PATCH 16/29] Expand note on GetModuleNamespace. --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 552c29fe60..ae09e7e5d4 100644 --- a/spec.html +++ b/spec.html @@ -21916,7 +21916,7 @@

    Runtime Semantics: GetModuleNamespace( _module_ )

    1. Return _namespace_. -

    The only way GetModuleNamespace can throw is via one of the triggered HostResolveImportedModule calls.

    +

    The only way GetModuleNamespace can throw is via one of the triggered HostResolveImportedModule calls. Unresolvable names are simply excluded from the namespace at this point. They will lead to a real instantiation error later unless they are all ambiguous star exports that are not explicitly requested anywhere.

    From 1488b0db456630653116ab538ee9d26ff39615b9 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Thu, 22 Jun 2017 16:02:15 +0200 Subject: [PATCH 17/29] Fix recording of resolution error in innocent module. --- spec.html | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/spec.html b/spec.html index ae09e7e5d4..e6b38aea95 100644 --- a/spec.html +++ b/spec.html @@ -21638,16 +21638,24 @@

    GetExportedNames( _exportStarSet_ ) Concrete Method

    -

    Runtime Semantics: ResolutionFailure( _module_, _resolveMode_ )

    +

    Runtime Semantics: ResolutionFailure( _resolveMode_ )

    The ResolutionFailure abstract operation performs the following steps:

    - 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. 1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*. 1. Assert: _resolveMode_ is `"normal"`. - 1. Let _error_ be Completion{[[Type]]: ~throw~, [[Value]]: a newly created *SyntaxError* object, [[Target]]: ~empty~}. - 1. Set _module_.[[ErrorCompletion]] to _error_. - 1. Set _module_.[[Status]] to `"errored"`. - 1. Return _error_. + 1. Throw a new *SyntaxError* exception. + +
    + + +

    Runtime Semantics: PropagateResolution( _module_, _resolution_ )

    +

    The PropagateResolution abstract operation performs the following steps:

    + + 1. If _resolution_ is an abrupt completion, then + 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. + 1. Set _module_.[[Status]] to `"errored"`. + 1. Set _module_.[[ErrorCompletion]] to _resolution_. + 1. Return _resolution_.
    @@ -21661,7 +21669,7 @@

    ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete MethodResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method @@ -21776,7 +21783,8 @@

    Runtime Semantics: ModuleDeclarationResolution( _module_ )

    1. Perform ! _envRec_.CreateImmutableBinding(_in_.[[LocalName]], *true*). 1. Call _envRec_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, - 1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], `"normal"`, « »). + 1. Let _resolution_ be _importedModule_.ResolveExport(_in_.[[ImportName]], `"normal"`, « »). + 1. Perform ? PropagateResolution(_module_, _resolution_). 1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). 1. Let _code_ be _module_.[[ECMAScriptCode]]. 1. Let _varDeclarations_ be the VarScopedDeclarations of _code_. From 7af3c50ed7d2c031a5390b28bd99100d8759fdcb Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Thu, 22 Jun 2017 16:53:30 +0200 Subject: [PATCH 18/29] Fix passing of dfs index. --- spec.html | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/spec.html b/spec.html index e6b38aea95..94855990f7 100644 --- a/spec.html +++ b/spec.html @@ -21726,7 +21726,7 @@

    ModuleDeclarationInstantiation( ) Concrete Method

    1. Return _result_. 1. Assert: _module_.[[Status]] is `"instantiated"` or `"evaluated"`. 1. Assert: _stack_ is empty. - 1. Return _result_. + 1. Return *undefined*. @@ -21735,19 +21735,21 @@

    Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ 1. If _module_ is not a Source Text Module Record, 1. Assert: _module_.[[Status]] is not `"instantiating"`. - 1. Return _module_.ModuleDeclarationInstantiation(). + 1. Perform ? _module_.ModuleDeclarationInstantiation(). + 1. Return _index_. 1. If _module_.[[Status]] is `"instantiating"`, `"instantiated"`, or `"evaluated"`, - 1. Return *undefined*. + 1. Return _index_. 1. If _module_.[[Status]] is `"errored"`, 1. Return _module_.[[ErrorCompletion]]. 1. Assert: _module_.[[Status]] is `"uninstantiated"`. 1. Set _module_.[[Status]] to `"instantiating"`. 1. Set _module_.[[DFSIndex]] to _index_. 1. Set _module_.[[DFSAncestorIndex]] to _index_. + 1. Set _index_ to _index_ + 1. 1. Append _module_ to _stack_. 1. For each String _required_ that is an element of _module_.[[RequestedModules]], 1. Let _requiredModule_ be ? HostResolveImportedModule(_module_, _required_). - 1. Perform ? InnerModuleDeclarationInstantiation(_requiredModule_, _stack_, _index_+1). + 1. Set _index_ to ? InnerModuleDeclarationInstantiation(_requiredModule_, _stack_, _index_). 1. Assert: _requiredModule_.[[Status]] is either `"instantiating"`, `"instantiated"`, or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`instantiating`" if and only if _requiredModule_ is in _stack_. 1. If _requiredModule_.[[Status]] is "`instantiating`", set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). @@ -21759,7 +21761,7 @@

    Runtime Semantics: InnerModuleDeclarationInstantiation( _module_, _stack_, _ 1. Remove this element from _stack_. 1. Set _requiredModule_.[[Status]] to "`instantiated`". 1. If _requiredModule_ is _module_, end the repetition. - 1. Return *undefined*. + 1. Return _index_. @@ -21827,7 +21829,7 @@

    ModuleEvaluation( ) Concrete Method

    1. Return _result_. 1. Assert: _module_.[[Status]] is `"evaluated"`. 1. Assert: _stack_ is empty. - 1. Return _result_. + 1. Return *undefined*.
    @@ -21836,20 +21838,22 @@

    Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

    1. If _module_ is not a Source Text Module Record, 1. Assert: _module_.[[Status]] is not `"evaluating"`. - 1. Return _module_.ModuleEvaluation(). + 1. Perform ? _module_.ModuleEvaluation(). + 1. Return _index_. 1. If _module_.[[Status]] is `"evaluating"` or `"evaluated"`, - 1. Return *undefined*. + 1. Return _index_. 1. If _module_.[[Status]] is `"errored"`, 1. Return _module_.[[ErrorCompletion]]. 1. Assert: _module_.[[Status]] is `"instantiated"`. 1. Set _module_.[[Status]] to `"evaluating"`. 1. Set _module_.[[DFSIndex]] to _index_. 1. Set _module_.[[DFSAncestorIndex]] to _index_. + 1. Set _index_ to _index_ + 1. 1. Append _module_ to _stack_. 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). 1. NOTE: ModuleDeclarationInstantiation must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. - 1. Perform ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_ + 1). + 1. Set _index_ to ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_). 1. Assert: _requiredModule_.[[Status]] is either `"evaluating"` or `"evaluated"`. 1. Assert: _requiredModule_.[[Status]] is "`evaluating`" if and only if _requiredModule_ is in _stack_. 1. If _requiredModule_.[[Status]] is "`evaluating`", set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). @@ -21861,7 +21865,7 @@

    Runtime Semantics: InnerModuleEvaluation( _module_, _stack_, _index_ )

    1. Remove this element from _stack_. 1. Set _requiredModule_.[[Status]] to "`evaluated`". 1. If _requiredModule_ is _module_, end the repetition. - 1. Return *undefined*. + 1. Return _index_.
    From 8f4dc944fd786e40a58978685da30739351dd8a5 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Thu, 22 Jun 2017 19:06:24 +0200 Subject: [PATCH 19/29] Compare against *undefined*, not *null*. --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 94855990f7..b770e49e20 100644 --- a/spec.html +++ b/spec.html @@ -21694,7 +21694,7 @@

    ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method Date: Thu, 22 Jun 2017 19:48:44 +0200 Subject: [PATCH 20/29] Weaken an assertion (we may revisit a module during error propagation). --- spec.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spec.html b/spec.html index b770e49e20..c2cefdb4d5 100644 --- a/spec.html +++ b/spec.html @@ -21652,9 +21652,12 @@

    Runtime Semantics: PropagateResolution( _module_, _resolution_ )

    The PropagateResolution abstract operation performs the following steps:

    1. If _resolution_ is an abrupt completion, then - 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. - 1. Set _module_.[[Status]] to `"errored"`. - 1. Set _module_.[[ErrorCompletion]] to _resolution_. + 1. If _module_.[[Status]] is `"errored"`, then + 1. Assert: _module_.[[ErrorCompletion]] is _resolution_. + 1. Otherwise, + 1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. + 1. Set _module_.[[Status]] to `"errored"`. + 1. Set _module_.[[ErrorCompletion]] to _resolution_. 1. Return _resolution_. From 45b4d8a2e4b23bf3a376616222acc4e01ba574eb Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 7 Jul 2017 17:54:00 -0400 Subject: [PATCH 21/29] Document all the module methods/abstract ops Also rearrange some of them to stay underneath their only users --- spec.html | 148 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 46 deletions(-) diff --git a/spec.html b/spec.html index c2cefdb4d5..6015885f90 100644 --- a/spec.html +++ b/spec.html @@ -21035,7 +21035,7 @@

    Abstract Module Records

- GetExportedNames(exportStarSet) + GetExportedNames(_exportStarSet_) Return a list of all names that are either directly or indirectly exported from this module. @@ -21043,10 +21043,11 @@

Abstract Module Records

- ResolveExport(exportName, resolveMode, resolveSet) + ResolveExport(_exportName_, _resolveMode_, _resolveSet_) - Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: Module Record, [[BindingName]]: String}. Return *null* if the name cannot be resolved, or `"ambiguous"` if multiple bindings were found. +

Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: Module Record, [[BindingName]]: String}. Return *null* if the name cannot be resolved, or `"ambiguous"` if multiple bindings were found.

+

The provided _resolveMode_ will be one of `"normal"` or `"namespace"`, indicating what type of export is being resolved.

- Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. If [[Status]] is "`instantiating`" or "`evaluating`", this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly-connected component. + Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. If [[Status]] is "`instantiating`" or "`evaluating`", this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component.
- ModuleDeclarationInstantiation() + Instantiate()

Transitively resolve all module dependencies and create a module Environment Record for the module.

@@ -21061,7 +21061,7 @@

Abstract Module Records

- ModuleEvaluation() + Evaluate()

Transitively evaluate all module dependencies of this module and then evaluate this module.

@@ -21079,7 +21079,7 @@

Source Text Module Records

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text () that was parsed using the goal symbol |Module|. Its fields contain digested information about the names that are imported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module.

-

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type. However, non-source text Module Records must not participate in dependency cycles with Source Text Module Records. Concretely, this is enforced below by assertions that non-source text Module Record dependencies do not have a [[Status]] of `"instantiating"` or `"evaluating"` during a call to ModuleDeclarationInstantiation or ModuleEvaluation on a Source Text Module Record.

+

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type. However, non-source text Module Records must not participate in dependency cycles with Source Text Module Records. Concretely, this is enforced below by assertions that non-source text Module Record dependencies do not have a [[Status]] of `"instantiating"` or `"evaluating"` during a call to Instantiate or Evaluate on a Source Text Module Record.

In addition to the fields, defined in , Source Text Module Records have the additional fields listed in . Each of these fields is initially set in ParseModule.

@@ -21171,7 +21171,7 @@

Source Text Module Records

Integer | *undefined*
- Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. + Auxiliary field used during Instantiate and Evaluate only. If [[Status]] is "`instantiating`" or "`evaluating`", this non-negative number records the point at which the module was first visited during the ongoing depth-first traversal of the dependency graph.
- Auxiliary field used during ModuleDeclarationInstantiation and ModuleEvaluation only. If [[Status]] is "`instantiating`" or "`evaluating`", this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component. + Auxiliary field used during Instantiate and Evaluate only. If [[Status]] is "`instantiating`" or "`evaluating`", this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component.
- ResolveExport(_exportName_, _resolveMode_, _resolveSet_) + ResolveExport(_exportName_, _resolveSet_) -

Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: Module Record, [[BindingName]]: String}. Return *null* if the name cannot be resolved, or `"ambiguous"` if multiple bindings were found.

-

The provided _resolveMode_ will be one of `"normal"` or `"namespace"`, indicating what type of export is being resolved.

+

Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: Module Record, [[BindingName]]: String}. If the name cannot be resolved, return either the module record that is to blame for the resolution failure or *null* in case there isn't any.

-

Transitively resolve all module dependencies and create a module Environment Record for the module.

+

Prepare the module for evaluation by transitively resolving all module dependencies and creating a module Environment Record.

Will transition this module's [[Status]] from `"uninstantiated"` to either `"instantiated"` or `"errored"`. While this is executing, this module's [[Status]] will be `"instantiating"`; this is observable through reentrant invocations via circular dependencies.

-

Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: Module Record, [[BindingName]]: String}. If the name cannot be resolved, return either the module record that is to blame for the resolution failure or *null* in case there isn't any.

+

Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: Module Record, [[BindingName]]: String}. If the name cannot be resolved, return either the module record that is to blame for the resolution failure or, in case there isn't any, return *null* or `"ambiguous`" depending on the nature of the failure.