ModuleDeclarationInstantiation behaviour after failure
allen at wirfs-brock.com
Mon Jul 18 18:04:03 UTC 2016
> On Jul 18, 2016, at 7:04 AM, Jon Coppeard <jcoppeard at mozilla.com> wrote:
> On 15/07/2016 18:36, Allen Wirfs-Brock wrote:
>> ModuleDeclarationInstantiation is a semantics of the ES spec. and it
>> isn’t clear to me why the HTML spec. would need to invoke it.
> The HTML spec needs some way of linking and executing modules. It's not
> clear (to me) which parts of ES can be "called into" and referred to
> externally from another spec.
The intent is that after the “host” has fetched a module (and its dependencies) it enqueue a TopLevelModuleEvaluationJob. But, as stated there, much of the work of that TopLevelModuleEvaluationJob can be performed eagerly.
> I guess at this point HTML is providing the source texts required by
> RunJobs step 2:
> "In an implementation dependent manner, obtain the ECMAScript source
> texts ... for zero or more ECMAScript scripts and/or ECMAScript modules”
That’s the “fetch” process, it’s completely host/implementation defined
RunJobs is dealing with an initial set of prefetched sequentially evaluated scripts and modules. This would probably include the inline sequentially evaluated scripts/modules within an HTML file. It wouldn’t include any deferred scripts/modules. A host handles deferred or dynamically identified scripts/modules (eg, via dynamically inserting a script tag into the DOM) by enqueuing additional Script/TopLevelModuleEvaluationJobs after RubJobs has already occurred.
> I'm still not sure how I would refer to that exactly from an external spec.
The external spec.describes the process of fetching the source text and then either says that it performs RunJobs (if hit is initiating a new ES engine instantiation) or performs EnqueueJob to create a ScriptEvaluationJob or a TopLevelModuleEvaluationJob.
> Further to this, if we do pre-instantiation of modules then we need some
> way of making this happen before TopLevelModuleEvaluationJob runs. I
> don't think saying something like "use an implementation specific way to
> pre-instantiate a module" would be that useful, whereas saying "call
> ModuleDeclarationInstantiation for the module record" makes it clear
> what is supposed to happen.
In a loader spec. that is expect to have multiple implementations (eg, the HTML module loader) you want to be careful to not over-specify things that should be implementation details. For example, whether or not modules are (fully) eagerly or asynchronously parsed should be something an implementation should be able to decide.
The only real requirement on a TopLevelEvaluationJob is the one implied by step 8.a of https://tc39.github.io/ecma262/#sec-moduledeclarationinstantiation <https://tc39.github.io/ecma262/#sec-moduledeclarationinstantiation> “Before instantiating a module, all of the modules it requested must be available.” By “module” here, it is really talking about the source code of a module. So, before enqueuing such a job the host needs to ensure that all the transitively referenced source modules are available. An implementation could perform a full parse of the module (as specified by https://tc39.github.io/ecma262/#sec-parsemodule <https://tc39.github.io/ecma262/#sec-parsemodule>) but an implementation might also work out a simpler way to identify a module’s dependencies that doesn’t require a full parse/static semantics analysis. So, you want to be careful not to transitively “call” ParseModule in your spec. to satisfy that requirement. Instead, you might use language like: “Determine, as if by recursively invoking PaarseModule, that all module source texts imported by the top level module are available.”
The primary interface from the ES spec. back into a loader is https://tc39.github.io/ecma262/#sec-hostresolveimportedmodule <https://tc39.github.io/ecma262/#sec-hostresolveimportedmodule> . ES expect to get a Module Record for a fully parsed/analyzed source module back from that. Something that isn’t said there (but probably should be) is that if the referenced module is is a source text module (there can be other, host/implementation defined kinds of modules that are defined using the ES Module grammar) then ParseModule must be “called” to produce the corresponding Source Text Module Record.
I would expect any host spec. for MostResolveImportedModule to roughly follow this pattern:
Use referencingModule and specifier to obtain a host internal module id, mid.
If the host known module registry has an entry for mid, then return the Module Record associated with mid in the registry.
If mid identifies a source text module, then
Assert: The source text of the module has already been fetched
Let src be the source text identified by mid.
Let modRec be ?ParseModule(src, currentRealm, hostProvided).
Create an entry in the host known module registry for mid that associates mid with modRec.
handle other implementation specified kinds of modules
Finally, I want to emphasize one more time that Module Records, as defined in the ES spec, are just an abstraction of the spec. They may or may not correspond to actual descrete records in an implementation. The data structures that a loader uses to track modules are not necessarily concrete Module Records and may have additional semantics that are specific to the loader/host environment. The only requirements on the association between the loader’s concept of a “module” and ES’s Module Record abstraction are those given in https://tc39.github.io/ecma262/#sec-hostresolveimportedmodule <https://tc39.github.io/ecma262/#sec-hostresolveimportedmodule>
> I think you're right. I'm not sure exactly what I had in mind but it
> seems the answer is "do anything you like as long as it is not
> observable to script", which is a lower bar than I realized.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss