-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Store and rethrow module instantiation/evaluation errors #916
Changes from 1 commit
99447ee
8cbe21b
2efb2f6
0f36dba
2a7239f
f385bdf
c1e0b95
59d782a
6ae9fef
ccc15d5
0cbc172
161fae3
ceee6fe
95ca7e6
0194216
87742a5
1488b0d
7af3c50
8f4dc94
5df3cfb
45b4d8a
643843d
c634359
a9bc302
6f491c4
c9b0565
f19fcde
b899bb7
152c344
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8301,8 +8301,7 @@ <h1>[[Get]] ( _P_, _Receiver_ )</h1> | |
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 @@ <h1>Abstract Module Records</h1> | |
</tr> | ||
<tr> | ||
<td> | ||
ResolveExport(exportName, resolveSet) | ||
ResolveExport(exportName, resolveMode, resolveSet) | ||
</td> | ||
<td> | ||
Return the binding of a name exported by this module. Bindings are represented by a <dfn id="resolvedbinding-record">ResolvedBinding Record</dfn>, 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 @@ <h1>GetExportedNames( _exportStarSet_ ) Concrete Method</h1> | |
</emu-note> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-resolutionfailure" aoid="ResolutionFailure"> | ||
<h1>Runtime Semantics: ResolutionFailure( _module_, _resolveMode_ )</h1> | ||
<p>The ResolutionFailure abstract operation performs the following steps:</p> | ||
<emu-alg> | ||
1. Assert: _module_.[[Status]] is `"uninstantiated"` or `"instantiating"`. | ||
1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*. | ||
1. Assert: _resolveMode_ is `"default"`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably should rename "default" to "normal" to avoid confusion with default export. |
||
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_. | ||
</emu-alg> | ||
</emu-clause> | ||
|
||
<!-- es6num="15.2.1.16.3" --> | ||
<emu-clause id="sec-resolveexport"> | ||
<h1>ResolveExport( _exportName_, _resolveSet_ ) Concrete Method</h1> | ||
<p>The ResolveExport concrete method of a Source Text Module Record with arguments _exportName_, and _resolveSet_ performs the following steps:</p> | ||
<h1>ResolveExport( _exportName_, _resolveMode_, _resolveSet_ ) Concrete Method</h1> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think object equality usually calls "SameValue" or some such? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a completion value though, so SameValue doesn't quite apply. Cf. "Assert: module.[[Realm]] is not undefined." |
||
<p>The ResolveExport concrete method of a Source Text Module Record with arguments _exportName_, _resolveMode_, and _resolveSet_ performs the following steps:</p> | ||
<emu-alg> | ||
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 @@ <h1>ResolveExport( _exportName_, _resolveSet_ ) Concrete Method</h1> | |
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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the check should be against undefined here, not against null. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, thanks. |
||
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_); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No underscores around ResolutionFailure (here and elsewhere) |
||
1. Otherwise, return _starResolution_. | ||
</emu-alg> | ||
<emu-note> | ||
<p>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_.</p> | ||
|
@@ -21691,7 +21711,7 @@ <h1>ModuleDeclarationInstantiation( ) Concrete Method</h1> | |
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 @@ <h1>Runtime Semantics: ModuleDeclarationResolution( _module_ )</h1> | |
<p>The ModuleDeclarationResolution abstract operation performs the following steps:</p> | ||
<emu-alg> | ||
1. For each ExportEntry Record _e_ in _module_.[[IndirectExportEntries]], do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting the module status to "evaluated" at this point will cause an infinite loop if we have a cycle in the module graph. We either need to set this earlier or set an 'evaluating' status while a module is evaluating. |
||
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 @@ <h1>Runtime Semantics: ModuleDeclarationResolution( _module_ )</h1> | |
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 @@ <h1>Runtime Semantics: GetModuleNamespace( _module_ )</h1> | |
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_. | ||
</emu-alg> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|module| here is the exporter rather than the importer, so I think it's fine for this to be in any state, except possibly "errored".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this didn't do what I intended, as I discovered earlier today. We shouldn't be recording the error in module. I've just uploaded a revised version.