Skip to content
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

Closed
wants to merge 29 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
99447ee
Store and rethrow module instantiation/evaluation errors
domenic May 11, 2017
8cbe21b
Fix module instantiation and evaluation.
GeorgNeis May 18, 2017
2efb2f6
Tweaks
domenic May 30, 2017
0f36dba
Assert no bad cycles, instead of throwing
domenic May 30, 2017
2a7239f
Fix fake xref
domenic May 30, 2017
f385bdf
Fix inaccurate note about initial value
domenic May 30, 2017
c1e0b95
Make "Source Text Module Record" link to its dfn
domenic May 30, 2017
59d782a
Assume HostResolveImportedModule never fails.
GeorgNeis Jun 2, 2017
6ae9fef
Record error where it happens.
GeorgNeis Jun 19, 2017
ccc15d5
Fix editorial issues
domenic Jun 19, 2017
0cbc172
Revert "Assume HostResolveImportedModule never fails."
GeorgNeis Jun 20, 2017
161fae3
Rename resolve mode "default" to "normal".
GeorgNeis Jun 20, 2017
ceee6fe
Add two invariants.
GeorgNeis Jun 20, 2017
95ca7e6
Account for exception in caller of ResolveExport...
GeorgNeis Jun 20, 2017
0194216
Update note on ResolveExport.
GeorgNeis Jun 20, 2017
87742a5
Expand note on GetModuleNamespace.
GeorgNeis Jun 20, 2017
1488b0d
Fix recording of resolution error in innocent module.
GeorgNeis Jun 22, 2017
7af3c50
Fix passing of dfs index.
GeorgNeis Jun 22, 2017
8f4dc94
Compare against *undefined*, not *null*.
GeorgNeis Jun 22, 2017
5df3cfb
Weaken an assertion (we may revisit a module during error propagation).
GeorgNeis Jun 22, 2017
45b4d8a
Document all the module methods/abstract ops
domenic Jul 7, 2017
643843d
More minor tweaks
domenic Jul 7, 2017
c634359
Add example STMR graphs section
domenic Jul 7, 2017
a9bc302
Bonus change: rename ModuleDeclarationInstantiation -> Instantiate, M…
domenic Jul 7, 2017
6f491c4
Typo/style fixes
domenic Jul 7, 2017
c9b0565
Remove ResolveExport's resolveMode argument.
GeorgNeis Jul 21, 2017
f19fcde
Revise various explanations of module operations and examples.
GeorgNeis Jul 24, 2017
b899bb7
Consistify diagram module names
domenic Jul 27, 2017
152c344
Preserve behavior concerning ambiguous export errors.
GeorgNeis Jul 27, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 40 additions & 23 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -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_, &laquo; &raquo;).
1. Assert: _binding_ is neither *null* nor `"ambiguous"`.
1. Let _binding_ be ! _m_.ResolveExport(_P_, `"default"`, &laquo; &raquo;).
1. Let _targetModule_ be _binding_.[[Module]].
1. Assert: _targetModule_ is not *undefined*.
1. Let _targetEnv_ be _targetModule_.[[Environment]].
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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"`.
Copy link

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".

Copy link
Contributor

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.

1. If _resolveMode_ is `"namespace"` or `"star"`: return *undefined*.
1. Assert: _resolveMode_ is `"default"`.
Copy link
Member Author

Choose a reason for hiding this comment

The 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>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think object equality usually calls "SameValue" or some such?

Copy link
Member Author

Choose a reason for hiding this comment

The 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
Expand All @@ -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,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the check should be against undefined here, not against null.

Copy link
Contributor

Choose a reason for hiding this comment

The 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_);
Copy link
Member Author

Choose a reason for hiding this comment

The 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>
Expand All @@ -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_.
Expand Down Expand Up @@ -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
Copy link

Choose a reason for hiding this comment

The 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]], &laquo; &raquo;).
1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception.
1. Perform ? _module_.ResolveExport(_e_.[[ExportName]], `"default"`, &laquo; &raquo;).
1. Assert: All named exports from _module_ are resolvable.
1. Let _realm_ be _module_.[[Realm]].
1. Assert: _realm_ is not *undefined*.
Expand All @@ -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]], &laquo; &raquo;).
1. If _resolution_ is *null* or _resolution_ is `"ambiguous"`, throw a *SyntaxError* exception.
1. Let _resolution_ be ? _importedModule_.ResolveExport(_in_.[[ImportName]], `"default"`, &laquo; &raquo;).
1. Call _envRec_.CreateImportBinding(_in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]).
1. Let _code_ be _module_.[[ECMAScriptCode]].
1. Let _varDeclarations_ be the VarScopedDeclarations of _code_.
Expand Down Expand Up @@ -21893,9 +21911,8 @@ <h1>Runtime Semantics: GetModuleNamespace( _module_ )</h1>
1. Let _exportedNames_ be ! _module_.GetExportedNames(&laquo; &raquo;).
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_, &laquo; &raquo;).
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"`, &laquo; &raquo;).
1. If _resolution_ is not *undefined*, append _name_ to _unambiguousNames_.
1. Set _namespace_ to ModuleNamespaceCreate(_module_, _unambiguousNames_).
1. Return _namespace_.
</emu-alg>
Expand Down