20:50
<Kris Kowal>
Caridy (and by association Daniel) have convinced me that we can use importMeta as in new Module(source, importHook, importMeta) and in importHook(importSpecifier, importMeta) to stand in for a “referrer” and that every host environment would still be able to emulate every other host environment. The key is that importMeta is object identical in these cases so can be used to carry a gensym or as a key in a WeakMap, even though it’s not identical to the import.meta that the evaluated module sees (unless we change that in ecma262 too!).
20:52
<Kris Kowal>
Caridy and I have also come to an agreement that the next revision of the compartments proposal will reify the constructor named Module since we believe module harmony will likely mean module {} instanceof Module, where Module(source, importHook, importMeta) generates unlinked, linkable, initializable instances of modules.
20:56
<Kris Kowal>
I’ve also agreed that there’s no need for the module constructor to ever have an option to override the execution context of the module instances it creates. We can carve out a supplemental proposal for a reified new ExecutionContext() that would carry new evaluators eval, Function, and Module bound to the same [[Realm]]. Between Module, ModuleSource, and ExecutionContext, we would have everything we need to build compartments in user code. We could still go on to provide a Compartment constructor in the language, but the motivation would be ergonomics and performance, and would be entirely orthogonal to these primitives, which we agree ought to be exposed.
21:10
<Kris Kowal>
I’ve also convinced myself that, if module instances locally memoize the results of their importHook for both static and dynamic import, and since the import hook returns module instances, we can induce that import is sufficiently idempotent in aggregate to prevent all useful surprises. Compartments allow for those memos to be slightly more economical with memory, but probably not in any meaningful way in practice. Again, no reason we couldn’t have both in the fullness of time, but I’m convinced we should focus on the Module and ModuleSource primitives.
21:13
<Kris Kowal>
I also believe that there is no better contender for the enormously self-assured name Module. My expectation is that Module will be backed by the Last Module Record type we ever need and that all meaningful extensions to the module system are different kinds of module source, not new kinds of module instance.
21:19
<Kris Kowal>
Caridy is focusing on a minimal layer that achieves parity with the current behaviors of ecma262, just reifying these two functions. I propose, in addition, that the Module constructor receives a Module Source Protocol implementation object, like {bindings?, initialize?, needsDynamicImport?, needsImportMeta?} which instances of ModuleSource happen to provide. This would be sufficient to define JSON, CommonJS, WASM, &c module sources in user code. However, that protocol would not be adequate to carry CSP information for vetted module sources and would not preclude the introduction of other host-defined module source classes. I expect only host-defined module source classes would be transmissible via structured clone and cary host-vetted origin metadata.
21:21
<Kris Kowal>
I’ve also been convinced that the first argument to initialize should be called a Module Imports Namespace Exotic Object (not a reification of the entire definition of Module Environment Record, just an exotic object that can be used to get and set the import and export bindings of the module, in its internal namespace.