-
Notifications
You must be signed in to change notification settings - Fork 72
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
Compartment support for dynamic import and importMetaHook #291
Labels
kriskowal-reviewed-2024-01
Issues that kriskowal is satisfied do not need attention from team bug review as of January, 2024
Comments
This was referenced Apr 20, 2022
naugtur
added a commit
that referenced
this issue
Apr 25, 2022
6 tasks
kriskowal
added
the
kriskowal-reviewed-2024-01
Issues that kriskowal is satisfied do not need attention from team bug review as of January, 2024
label
Jan 10, 2024
kriskowal
added a commit
that referenced
this issue
Nov 26, 2024
Closes: #291 ## Description This change adds support for dynamic `import` to `ses` and `@endo/module-source`, such that `import(x)` in the scope of a module loaded from source (using `ModuleSource` in a `Compartment` module loading hook). ### Security Considerations This change builds on prior work to ensure that dynamic import is facilitated by a hidden lexical name injected by `ses`. The dynamic import mechanism is isolated to the surrounding compartment and specifiers are resolved on the surrounding module. ### Scaling Considerations This change introduces a static analysis for the presence of a dynamic `import` in the module source, which it communicates on the module source, even if marshaled through JSON, to `ses` that it should create an `import` closure bound to the calling module’s base specifier. This avoids an allocation for most modules. ### Documentation Considerations Only news included. Dynamic import is a language feature that is expected to work in general and documented where JavaScript is documented as a language. ### Testing Considerations This change includes a minimal happy path test that verifies that dynamic import produces a promise that settles on a module namespace object. Note that dynamic import does not box namespaces regardless of the `__noNamespaceBox__` compartment option. ### Compatibility Considerations Backward compatible. ### Upgrade Considerations None.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
kriskowal-reviewed-2024-01
Issues that kriskowal is satisfied do not need attention from team bug review as of January, 2024
[update April 20, 2022]:
Description
SES shim should support the features of dynamic import (
import
) and import metadata (import.meta
). These must be implemented in a manner that is host neutral and afford the possibility of lazy, on-demand initialization ofimport.meta
for use cases likeimport.meta.resolve
that would be prohibitively expensive if constructed for modules that do not utterimport.meta
in their source.Design
In
@endo/static-module-record
we employ a source to source transformation that produces a “first-party static module record” thatses
understands how to load, link, and initialize when returned through theimportHook
. In SES, themodule-instance.js
module is responsible for the runtime component for evaluating modules. We must extend this calling convention to support dynamic import and import metadata.Also, because static module records are committed to archives and stored, the calling convention for modules generated by older versions of
@endo/static-module-record
must be preserved.I propose that we do this by rewriting dynamic
import(specifier)
andimport.meta
in the module-to-program transformation to forms like$h_import()
and$h_import_meta
, including the ZWJ so the hidden symbol censorship still applies. The module-instance.js linker must pass suitable values for these into the generated module functor. The dynamic import function must be a closure that applies theresolveHook
relative to the currentmoduleSpecifier
.Since creating
$h_import_meta
and$h_import
are avoidable if they were not uttered by the source, or compiled by an earlier version of@endo/static-module-record
, the newerStaticModuleRecord
constructor should add new properties to the record, like__usesImport
and__usesImportMeta
, as an indication for whether these should be made.$h_import_meta
must be an object with anull
prototype.The
importHook
(to be calledloadHook
in a future revision #420) will need to be able to return a “module record envelope” that has an optionalmeta
property. Therecord.meta
property is an object to copy to the$h_import_meta
object, either with the semantics ofObject.assign($h_import_meta, record.meta)
orObject.defineProperties($h_import_meta, Object.getOwnPropertyDescriptors(record.meta))
, on which we need consensus among the champions of the TC39 Compartment Proposal.We would, either in this change or a future change to be factored out of this issue, also implement a
importMetaHook
. TheimportMetaHook
would receive$h_import_meta
and have an opportunity to augment it and freeze it before the object is revealed to guest code. The module machinery must only call the hook ifimport.meta
is uttered in the module code. The host function must not be called on the stack of guest code.We will need consensus among the Compartments champions for the time that the
importMetaHook
function must be called, but I’m guessing that the most obvious answer would be immediately before initializing the module, without any opportunity for other events to be interleaved. So, an exception thrown inimportMetaHook
would be observed as the permanent revocation of the promise for the initialization of the module, poisoning any module that depends on it.Security Considerations
The
$h_import
internal should not be utterable by guest code except as a function call. Access to the function object should not be possible. It should be frozen by module-instance.js on the off-chance that it is accidentally exposed to guest code.The
$h_import_meta
object must be freezable by either the host or the guest. The design ofimportMetaHook
affords this possibility. I suspect that TC39 will want theimport.meta
to be mutable unless the host or guest elects to freeze it, but on this we should also get consensus from the Compartment Proposal champions and eventually reviewers.[from #303, May 11, 2020]:
Code running in a compartment needs access to a dynamic
import
expression that closes over the compartment’s module loader. This should presentimport.meta
according to whatever is returned by the compartment’simportMetaHook(specifier)
.*[original, from May 4, 2020]:
Currently, transform-module does introduce an
import
endowment (need to verify). There is a note in the code that we need to add a facility for hardening the import function. The existing code also arranges for animport.meta
andimport.meta.url
and we need to instead facilitate weaving animportMetaHook
through theCompartment
constructor options to make this behavior customizable.The text was updated successfully, but these errors were encountered: