Skip to content

Commit 0ab780e

Browse files
Use the new HostLoadImportedModule ECMA-262 hook
1 parent 69183bd commit 0ab780e

File tree

1 file changed

+49
-72
lines changed

1 file changed

+49
-72
lines changed

spec.html

Lines changed: 49 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ <h1>EvaluateImportCall ( _specifierExpression_ [ , _optionsExpression_ ] )</h1>
103103
1. Append { [[Key]]: _key_, [[Value]]: _value_ } to _assertions_.
104104
1. Sort _assertions_ by the code point order of the [[Key]] of each element. NOTE: This sorting is observable only in that hosts are prohibited from distinguishing among assertions by the order they occur in.
105105
1. Let _moduleRequest_ be a new ModuleRequest Record { [[Specifier]]: _specifierString_, [[Assertions]]: _assertions_ }.
106-
1. Perform ! HostImportModuleDynamically(_referencingScriptOrModule_, _moduleRequest_, _promiseCapability_).
106+
1. Let _state_ be a new ModuleLoadState Record { [[Action]]: ~dynamic-import~, [[PromiseCapability]]: _promiseCapability_ }.
107+
1. Perform HostLoadImportedModule(_referrer_, _moduleRequest_, *undefined*, _state_).
107108
1. Return _promiseCapability_.[[Promise]].
108109
</emu-alg>
109110
</emu-clause>
@@ -120,39 +121,42 @@ <h1>EvaluateImportCall ( _specifierExpression_ [ , _optionsExpression_ ] )</h1>
120121
</emu-clause>
121122
</emu-clause>
122123

123-
<emu-clause id="sec-hostresolveimportedmodule" aoid="HostResolveImportedModule">
124-
<h1>Runtime Semantics: HostResolveImportedModule ( _referencingScriptOrModule_, <del>_specifier_</del> <ins>_moduleRequest_</ins> )</h1>
125-
<p>HostResolveImportedModule is an implementation-defined abstract operation that provides the concrete Module Record subclass instance that corresponds to <del>the |ModuleSpecifier| String, _specifier_,</del><ins>the ModuleRequest Record _moduleRequest_</del> occurring within the context of the script or module represented by the Script Record or Module Record _referencingScriptOrModule_. _referencingScriptOrModule_ may also be *null*, if the resolution is being performed in the context of an <emu-xref href="#sec-import-calls">`import()`</emu-xref> expression, and there is no active script or module at that time.</ins></p>
124+
<emu-clause id="sec-hostloadimportedmodule" aoid="HostLoadImportedModule">
125+
<h1>HostLoadImportedModule ( _referrer_, <del>_specifier_</del><ins>_moduleRequest_</ins>, _hostDefined_, _payload_ )</h1>
126+
<p>The host-defined abstract operation HostLoadImportedModule takes arguments _referrer_ (a Script Record, a Cyclic Module Record, or a Realm Record), <del>_specifier_ (a String)</del><ins>_moduleRequest_ (a ModuleRequest Record)</ins>, _hostDefined_ (anything), and _payload_ (a ModuleLoadState Record) and returns ~unused~.</p>
126127

127128
<emu-note>
128-
<p>An example of when _referencingScriptOrModule_ can be *null* is in a web browser host. There, if a user clicks on a control given by</p>
129+
<p>An example of when _referrer_ can be a Realm Record is in a web browser host. There, if a user clicks on a control given by</p>
129130

130131
<pre><code class="html">&lt;button type="button" onclick="import('./foo.mjs')"&gt;Click me&lt;/button&gt;</code></pre>
131132

132133
<p>there will be no active script or module at the time the <emu-xref href="#sec-import-calls">`import()`</emu-xref> expression runs. More generally, this can happen in any situation where the host pushes execution contexts with *null* ScriptOrModule components onto the execution context stack.</p>
133134
</emu-note>
134135

135-
<p>The implementation of HostResolveImportedModule must conform to the following requirements:</p>
136+
<p>An implementation of HostLoadImportedModule must conform to the following requirements:</p>
136137
<ul>
137138
<li>
138-
The normal return value must be an instance of a concrete subclass of Module Record.
139+
The host environment must perform FinishLoadingImportedModule(_referrer_, <del>_specifier_</del><ins>_moduleRequest_</ins>, _payload_, _result_), where _result_ is either a normal completion containing the loaded Module Record or a throw completion, either synchronously or asynchronously.
139140
</li>
140141
<li>
141-
If a Module Record corresponding to the pair _referencingScriptOrModule_, <del>_specifier_</del>, <ins>_moduleRequest_</ins> does not exist or cannot be created, an exception must be thrown.
142-
</li>
143-
<li>
144-
Each time this operation is called with a specific _referencingScriptOrModule_, <del>_specifier_ pair</del> <ins>_moduleRequest_.[[Specifier]], _moduleRequest_.[[Assertions]] triple</ins> as arguments it must return the same Module Record instance if it completes normally.
142+
<p>If this operation is called multiple times with the same <del>(_referrer_, _specifier_) pair</del><ins>(_referrer_, _moduleRequest_.[[Specifier]], _moduleRequest_.[[Assertions]]) triple</ins> and it performs FinishLoadingImportedModule(_referrer_, <del>_specifier_</del><ins>_moduleRequest_</ins>, _payload_, _result_) where _result_ is a normal completion, then it must perform FinishLoadingImportedModule(_referrer_, <del>_specifier_</del><ins>_moduleRequest_</ins>, _payload_, _result_) with the same _result_ each time.</p>
143+
144+
<p><ins>It is recommended but not required that implementations additionally conform to the following stronger constraint:</ins></p>
145145
<ul>
146146
<li>
147-
It is recommended but not required that implementations additionally conform to the following stronger constraint: each time this operation is called with a specific _referencingScriptOrModule_, _moduleRequest_.[[Specifier]] pair as arguments it must return the same Module Record instance if it completes normally.
147+
<ins>If this operation is called multiple times with the same (_referrer_, _moduleRequest_.[[Specifier]]) pair and it performs FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) where _result_ is a normal completion, then it must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) with the same _result_ each time.</ins>
148148
</li>
149149
</ul>
150150
</li>
151151
<li>
152152
<ins>_moduleRequest_.[[Assertions]] must not influence the interpretation of the module or the module specifier; instead, it may be used to determine whether the algorithm completes normally or with an abrupt completion.</ins>
153153
</li>
154+
<li>
155+
The operation must treat _payload_ as an opaque value to be passed through to FinishLoadingImportedModule.
156+
</li>
154157
</ul>
155-
<p>Multiple different _referencingScriptOrModule_, <del>_specifier_</del> <ins>_moduleRequest_.[[Specifier]]</ins> 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.</p>
158+
159+
<p>The actual process performed is host-defined, but typically consists of performing whatever I/O operations are necessary to load the appropriate Module Record. Multiple different (_referrer_, <del>_specifier_</del><ins>_moduleRequest_.[[Specifier]]</ins>) pairs may map to the same Module Record instance. The actual mapping semantic is host-defined but typically a normalization process is applied to <del>_specifier_</del><ins>_moduleRequest_.[[Specifier]]</ins> as part of the mapping process. A typical normalization process would include actions such as expansion of relative and abbreviated path specifiers.</p>
156160

157161
<emu-note type=editor>
158162
<p>The above text implies that is recommended but not required that hosts do not use _moduleRequest_.[[Assertions]] as part of the module cache key. In either case, an exception thrown from an import with a given assertion list does not rule out success of another import with the same specifier but a different assertion list.</p>
@@ -166,67 +170,40 @@ <h1>Runtime Semantics: HostResolveImportedModule ( _referencingScriptOrModule_,
166170
</emu-note>
167171
</emu-clause>
168172

169-
<emu-clause id="sec-hostimportmoduledynamically" aoid="HostImportModuleDynamically">
170-
<h1>Runtime Semantics: HostImportModuleDynamically ( _referencingScriptOrModule_, <del>_specifier_,<del> <ins>_moduleRequest_,</ins> _promiseCapability_ )</h1>
171-
<p>HostImportModuleDynamically is an implementation-defined abstract operation that performs any necessary setup work in order to make available the module corresponding to the <del>|ModuleSpecifier| String, _specifier_,</del><ins>ModuleRequest Record _moduleRequest_</ins> occurring within the context of the script or module represented by the Script Record or Module Record _referencingScriptOrModule_. (_referencingScriptOrModule_ may also be *null*, if there is no active script or module when the <emu-xref href="#sec-import-calls">`import()`</emu-xref> expression occurs.) It then performs FinishDynamicImport to finish the dynamic import process.</p>
172-
173-
174-
<p>The implementation of HostImportModuleDynamically must conform to the following requirements:</p>
175-
176-
<ul>
177-
<li>
178-
The abstract operation must always complete normally with *undefined*. Success or failure must instead be signaled as discussed below.
179-
</li>
180-
<li>
181-
The host environment must conform to one of the two following sets of requirements:
182-
<dl>
183-
<dt>Success path</dt>
184-
185-
<dd>
186-
<ul>
187-
<li>At some future time, the host environment must perform FinishDynamicImport(_referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_</ins>, _promiseCapability_, NormalCompletion(*undefined*)).</li>
188-
189-
<li>Any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments _referencingScriptOrModule_, and <del>_specifier_</del> <ins>_moduleRequest_</ins> must complete normally.</li>
190-
191-
<li>The completion value of any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments _referencingScriptOrModule_, and <del>_specifier_,</del> <ins>_moduleRequest_</ins> must be a module which has already been evaluated, i.e. whose Evaluate concrete method has already been called and returned a normal completion.</li>
192-
</ul>
193-
</dd>
194-
195-
<dt>Failure path</dt>
196-
197-
<dd>
198-
<ul>
199-
<li>At some future time, the host environment must perform FinishDynamicImport(_referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_,</ins> _promiseCapability_, an abrupt completion), with the abrupt completion representing the cause of failure.</li>
200-
</ul>
201-
</dd>
202-
</dl>
203-
</li>
204-
<li>
205-
If the host environment takes the success path once for a given _referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_</ins> pair, it must always do so for subsequent calls.
206-
</li>
207-
<li>
208-
The operation must not call _promiseCapability_.[[Resolve]] or _promiseCapability_.[[Reject]], but instead must treat _promiseCapability_ as an opaque identifying value to be passed through to FinishDynamicImport.
209-
</li>
210-
</ul>
211-
212-
<p>The actual process performed is implementation-defined, but typically consists of performing whatever I/O operations are necessary to allow HostResolveImportedModule to synchronously retrieve the appropriate Module Record, and then calling its Evaluate concrete method. This might require performing similar normalization as HostResolveImportedModule does.</p>
213-
</emu-clause>
214-
215-
<emu-clause id="sec-finishdynamicimport" aoid="FinishDynamicImport">
216-
<h1>Runtime Semantics: FinishDynamicImport ( _referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_,</ins> _promiseCapability_, _completion_ )</h1>
217-
<p>The abstract operation FinishDynamicImport takes arguments _referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_ (a ModuleRequest Record),</ins> _promiseCapability_, and _completion_. FinishDynamicImport completes the process of a dynamic import originally started by an <emu-xref href="#sec-import-calls">`import()`</emu-xref> call, resolving or rejecting the promise returned by that call as appropriate according to _completion_. It is performed by host environments as part of HostImportModuleDynamically. It performs the following steps when called:</p>
218-
173+
<emu-clause id="sec-FinishLoadingImportedModule" type="abstract operation">
174+
<h1>FinishLoadingImportedModule ( _referrer_, <del>_specifier_</del><ins>_moduleRequest_</ins>, _state_, _result_ )</h1>
175+
<p>The abstract operation FinishLoadingImportedModule takes arguments _referrer_ (a Script Record, a Cyclic Module Record, or a Realm Record), <del>_specifier_ (a String)</del><ins>_moduleRequest_ (a ModuleRequest Record)</ins>, _state_ (a ModuleLoadState Record), and _result_ (either a normal completion containing a Module Record or a throw completion) and returns ~unused~.</p>
219176

220177
<emu-alg>
221-
1. If _completion_ is an abrupt completion, then perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _completion_.[[Value]] »).
178+
1. If _result_ is a normal completion, then
179+
1. If _referrer_.[[LoadedModules]] contains a Record _record_ such that _record_.[[Specifier]] is _moduleRequest_.[[Specifier]] <ins>and AssertionsEqual(_record_.[[Assertions]], _moduleRequest_.[[Assertions]]) is *true*</ins>, then
180+
1. Assert: _record_.[[Module]] is _result_.[[Value]].
181+
1. Else, add Record { [[Specifier]]: _moduleRequest_.[[Specifier]], <ins>[[Assertions]]: _moduleRequest_.[[Assertions]]</ins>, [[Module]]: _result_.[[Value]] } to _referrer_.[[LoadedModules]].
182+
1. If _state_.[[Action]] is ~graph-loading~, then
183+
1. Perform ContinueModuleLoading(_state_, _result_).
222184
1. Else,
223-
1. Assert: _completion_ is a normal completion and _completion_.[[Value]] is *undefined*.
224-
1. Let _moduleRecord_ be ! HostResolveImportedModule(_referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_</ins>).
225-
1. Assert: Evaluate has already been invoked on _moduleRecord_ and successfully completed.
226-
1. Let _namespace_ be GetModuleNamespace(_moduleRecord_).
227-
1. If _namespace_ is an abrupt completion, perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _namespace_.[[Value]] »).
228-
1. Else, perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _namespace_.[[Value]] »).
185+
1. Perform ContinueDynamicImport(_state_, _result_).
229186
</emu-alg>
187+
188+
<emu-note type="editor">
189+
<p>The description of the [[LoadedModules]] field of Realm Record, Script Record, and Cyclic Module Record should be updated to include the [[Assertions]] field.</p>
190+
</emu-note>
191+
192+
<emu-clause id="sec-FinishLoadingImportedModule-AssertionsEqual" type="abstract operation">
193+
<h1><ins>AssertionsEqual(_left_, _right_)</ins></h1>
194+
<p>The abstract operation AssertionsEqual takes arguments _left_ and _right_ (two Lists of Records { [[Key]]: a String, [[Value]]: a String }), and returns a Boolean.</p>
195+
196+
<emu-alg>
197+
1. If the number of elements in _left_ is not the same as the number of elements in _right_, return *false*.
198+
1. For each Record { [[Key]], [[Value]] } _r_ of _left_, do
199+
1. Let _found_ be *false*.
200+
1. For each Record { [[Key]], [[Value]] } _s_ of _right_, do
201+
1. If _r_.[[Key]] is _s_.[[Key]] and _r_.[[Value]] is _s_.[[Value]], then
202+
1. Set _found_ to *true*.
203+
1. If _found_ is *false*, return *false*.
204+
1. Return *true*.
205+
</emu-alg>
206+
</emu-clause>
230207
</emu-clause>
231208

232209
<emu-clause id="sec-hostgetsupportedimportassertions" aoid="HostGetSupportedImportAssertions">
@@ -312,7 +289,7 @@ <h1>Static Semantics: StringValue</h1>
312289
<h1>ModuleRequest Records</h1>
313290

314291
<p>A <dfn>ModuleRequest Record</dfn> represents the request to import a module with given import assertions. It consists of the following fields:</p>
315-
<emu-table id="table-cyclic-module-fields" caption="ModuleRequest Record fields">
292+
<emu-table id="table-modulerequest-fields" caption="ModuleRequest Record fields">
316293
<table>
317294
<tbody>
318295
<tr>
@@ -558,7 +535,7 @@ <h1>Sample host integration: The Web embedding</h1>
558535

559536
<ul>
560537
<li>The <a href="https://html.spec.whatwg.org/#module-script">module script</a> would have an additional item, which would be the module type, as a string (e.g., *"json"*), or *undefined* for a JavaScript module.</li>
561-
<li>HostResolveImportedModule and HostImportModuleDynamically would take a ModuleRequest Record parameter in place of a specifier string, which would be passed down through several abstract operations to reach the <a href="https://html.spec.whatwg.org/#fetch-a-single-module-script">fetch a single module script</a> algorithm. Somewhere near the entrypoint, if the ModuleRequest Record's [[Assertions]] field has an element _entry_ such that _entry_.[[Key]] is *"type"*, then let _type_ be _entry_.[[Value]]; otherwise let _type_ be *undefined*. If the type is invalid, then an exception is thrown and module loading fails. Otherwise, this will equal the module type, if the module can be successfully fetched with a matching MIME type.</li>
538+
<li>HostLoadImportedModule would take a ModuleRequest Record parameter in place of a specifier string, which would be passed down through several abstract operations to reach the <a href="https://html.spec.whatwg.org/#fetch-a-single-module-script">fetch a single module script</a> algorithm. Somewhere near the entrypoint, if the ModuleRequest Record's [[Assertions]] field has an element _entry_ such that _entry_.[[Key]] is *"type"*, then let _type_ be _entry_.[[Value]]; otherwise let _type_ be *undefined*. If the type is invalid, then an exception is thrown and module loading fails. Otherwise, this will equal the module type, if the module can be successfully fetched with a matching MIME type.</li>
562539
<li>In the <a href="https://html.spec.whatwg.org/#fetch-the-descendants-of-a-module-script">fetch the descendents of a module script</a> algorithm, when iterating over [[RequestedModules]], the elements are ModuleRequest Records rather than just specifier strings; these Records is passed on to the internal module script graph fetching procedure (which sends it to "fetch a single module script". Other usage sites of [[RequestedModules]] ignore the assertion.</li>
563540
<li>"Fetch a single module script" would check the assertion in two places:
564541
<ul>

0 commit comments

Comments
 (0)