-
Notifications
You must be signed in to change notification settings - Fork 71
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
feat(ses): Add minimal Compartment to SES-lite #443
Conversation
1a8c928
to
b2235d7
Compare
505c63e
to
716bab1
Compare
b2235d7
to
a6e9a90
Compare
1df60b9
to
504a85c
Compare
return performEval(source, globalObject, globalLexicals, { | ||
let localObject = globalLexicals; | ||
if (localLexicals !== undefined) { | ||
localObject = create(null, getOwnPropertyDescriptors(globalLexicals)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can global lexicals be mutable? Are mutable global lexicals represented as mutable data properties, or as accessor properties whose getter and setter access captured state? If the latter, this seems to be fine. However, if they are represented as data properties, this will cause data properties with independent mutability, causing updates to be lost to the compartment-wide shared global lexical contour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
globalLexicals must be mutable to effect live bindings, when used to carry setters into module scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separately, I want to express a hip hip hoorah! for this reorganization. Each level is extraordinarily easier to understand, now that it has been disentangled from the other level. Even if we didn't need to do it for packaging reasons, it is something we should have done anyway for clarity.
Could we even split the levels into two packages, so that it is clear that there are no dependencies from the eval-only level to the module level?
IIUC our immediate plans for XS: Because they do not yet support dynamic module loading, we would use their Compartment
system almost exactly as an implementation of our eval-only level of abstraction. We would then build a module-supporting Compartment
on top of it exactly as the module level here builds on our own eval-only Compartment
. Could the module layer code in fact be the same --- be independent of how the eval-only Compartment
level is provided?
There's the gotcha with that we already know: The special evaluate
option we're using is not supported by Moddable and should never be. We should never ask them for that or propose that anyone else implement it. That means the only ES module code we cannot run through our translator and then on the Moddable compartments is code that exports live bindings. What's the best way to feature detect for whether this evaluate
option is supported? As long as we can detect and reliably signal an error, I don't think anyone running on XS will ever care about the absence of live bindings. And this restriction will disappear anyway once XS directly implements the full Compartment spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An interesting suggestion, and a correction to a previous review comment.
NOT URGENT: There is a further separation that this PR sets up, that will eventually be relevant to us, that I would like to understand. Most of the module layer code here is not concerned with translating module source text to evaluable strings. As long as these end up as static module records that do the right thing, most of the module layer code is happy. So if we were going to do offline untrusted translation, we'd still unburden ourselves from the parser, but we could use the rest of this module layer to do least authority linkage as driven by endo/lavamoat/tofu declarative policy config files. Building on the separation done by this PR, what would need to change to do that further separation? It would seem only another module kind handler that knows how to turn allegedly-pre-translated modules into static module records. Aside from live bindings, this would seem a smaller step than adding CJS modules. Anything else? |
Live bindings would be the only hard thing. CommonJS module support using the third-party static module record interface should continue to work fine. |
504a85c
to
8421159
Compare
0a3593a
to
f515029
Compare
8421159
to
b2a4499
Compare
f515029
to
141cbc3
Compare
0fa6a63
to
cbcd102
Compare
cbcd102
to
dc42004
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Looking forward to seeing this land!
"qt": "tap --no-esm --no-coverage --reporter spec 'test/**/*.test.js'", | ||
"test": "yarn build && yarn qt", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nice. I've already found it useful. We should propagate this pattern everywhere. Though not in this PR ;)
It might be sufficient to separate the How to make that coupling optional is a hard problem. It would be easier to provide a public-but-nonstandard static-modul-record interface that supports live-bindings. |
The
ses/lockdown
layer, and the Rollup bundles that we generate from it, will now contain aCompartment
withevaluate
, but without a module system. This is sufficient for containment, and doesn’t entrain a full JavaScript parser framework.