Isolated worlds (was Re: Module isolation)
Adam,
The 'isolated world' concept looks very interesting. But how is an "isolated world" accessed - is there an ES api:
evalCodeInIsolatedWorld("... ES source code ...");
Is there an web page you can point me to?
Isolated worlds point to the same underlying native DOM objects - so that DOM changes made in isolated world 'A' will be visible in isolated world 'B'
- even if the DOM wrappers have been tweaked in 'B'. Is there a way to only make part of the native DOM tree accessible to a isolated world?
Thanks.
Adam, The 'isolated world' concept looks very interesting. But how is an "isolated world" accessed - is there an ES api: evalCodeInIsolatedWorld("... ES source code ..."); Is there an web page you can point me to? Isolated worlds point to the same underlying native DOM objects - so that DOM changes made in isolated world 'A' will be visible in isolated world 'B' - even if the DOM wrappers have been tweaked in 'B'. Is there a way to only make part of the native DOM tree accessible to a isolated world? Thanks. On Mon, Jan 11, 2010 at 6:49 AM, Adam Barth <abarth-mozilla at adambarth.com>wrote: > [Re-sending now that I've subscribed with this address] > > I haven't been following this module discussion very closely, but > these recent comments sound related to something we've been playing > around with in WebKit. We have a mechanism (called an "isolated > world") that lets multiple JavaScript contexts share access to the > same DOM without ever exchanging JavaScript pointers with each other. > Essentially: > > 1) Each world gets it's own global object, complete with independent, > mutable built-in objects. > 2) Each world gets it's own set of (mutable) DOM wrappers. > > For those not familiar with the details of browser implementations, > JavaScript DOM objects are usually implemented as wrapper objects > around the "native" object, implemented in C++. Because each isolated > world gets its own wrappers, the usual one-to-one relation between the > native objects and it's wrapper is replaced with a one-to-many > relation. > > This trick works nicely because DOM is a language-neutral interface. > Just like you can have Python and JavaScript bindings for the DOM, > isolated worlds essentially lets you have JavaScriptA and JavaScriptB > bindings. The key invariant is that two worlds never exchange > JavaScript pointers (which you can think of as object-capabilities, if > you like), just like Python and JavaScript would never exchange > pointers if they interacted with the same DOM objects. > > I'm not sure this mechanism is directly applicable to future versions > of ECMAScript because we're able to implement it just fine using ES5. > However, it might be an approach worth considering in designing a > module system for ECMAScript. > > Adam > > > On Sun, Jan 10, 2010 at 9:38 PM, Brendan Eich <brendan at mozilla.com> wrote: > > On Jan 10, 2010, at 9:30 PM, David-Sarah Hopwood wrote: > > > >> Brendan Eich wrote: > >>> > >>> On Jan 10, 2010, at 1:14 AM, Kevin Curtis wrote: > >>> > >>>> From SecureEcmaScript proposal: > >>>> 6. The top level binding of this in an evaled Program is not the > >>>> global object, but rather a frozen root object containing just the > >>>> globals defined in the ES5 spec. > >>> > >>> For many current applications, the frozen |this| object is not > necessary > >>> or desirable in global code. The essential characteristic of modules, > >>> isolation for each module's "inside" from unimported effects of other > >>> modules, does not necessarily mean no mutation of primordial objects. > >> > >> On the contrary, it does necessarily mean that. If you can mutate > >> primordial objects, then there is no isolation of any module. There > >> may be a reduction in the possibilities for accidental interference > >> between modules, but that should be distinguished from isolation. > > > > Who said primordial objects are shared between modules? You assume too > much > > in assuming your favored conclusion. > > > > There are three things a module has to deal with to interact with JS in > > browsers: > > > > 1. The global object and its Object, Date, etc. primordials. > > 2. The |this| binding for "global" code in the module, at the module's > top > > level. > > 3. The scope chain tail object, the only object on the scope chain for > > global code in ES1-5. > > > > These are not necessarily the same at all. The lexical_scope proposal > > eliminates 3 by making the top-level a lexical environment, not an > object. > > The |this| binding may or may not refer to the global object. And it's > not > > settled whether, in browsers with many global objects (one per > > window/frame/iframe) there is only one global among N>1 modules, or a > global > > per module. > > > > If modules do not use free variables, only what they import, then you're > > wrong that isolation requires freezing. Modules could use their own > > primordials, or none (only library code, possibly better versions of > Date, > > etc.). The object and array initialisers and regexp literals would have > to > > construct using some "original value" of Object, Array, RegExp. But not > > necessarily a frozen one, if per-module. > > > > That you conflate frozen primordials with isolation is exactly the kind > of > > over-specification through shortest-path evolution of ES5 to which I > object. > > It is not going to fly in TC39 among all the browser vendors. We need to > > hear from Apple, Microsoft, and Opera, but I'm already objecting to this > > kind of axiom planting. Let's back up and talk about modules from > premises > > forward. > > > > /be > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20100112/4a8d1dec/attachment-0001.html>
On Mon, Jan 11, 2010 at 11:12 PM, Kevin Curtis <kevinc1846 at googlemail.com> wrote:
The 'isolated world' concept looks very interesting. But how is an "isolated world" accessed - is there an ES api: evalCodeInIsolatedWorld("... ES source code ..."); Is there an web page you can point me to?
Not exactly. They're used by the extension system for content scripts:
code.google.com/chrome/extensions/content_scripts.html#execution-environment
Essentially, they help protect an extension's content script from getting confused by the page manipulating it's JavaScript environment.
Isolated worlds point to the same underlying native DOM objects - so that DOM changes made in isolated world 'A' will be visible in isolated world 'B'
Yes.
- even if the DOM wrappers have been tweaked in 'B'.
That's right. The properties of the DOM objects captured by the various DOM Core, etc, specs are identical in the two worlds.
Is there a way to only make part of the native DOM tree accessible to a isolated world?
Not in our current implementation, but you could imagine doing that in the future. For the content scripts application, the content script has strictly greater privileges than the page it's running on. One way to think about that is that code in the isolated world can add a <script> tag to the document, which runs on the main world, just like
what would happen if Python interacting with the DOM added a <script>
tag.
Adam
On Mon, Jan 11, 2010 at 11:12 PM, Kevin Curtis <kevinc1846 at googlemail.com> wrote: > The 'isolated world' concept looks very interesting. But how is an "isolated > world" accessed - is there an ES api: > evalCodeInIsolatedWorld("... ES source code ..."); > Is there an web page you can point me to? Not exactly. They're used by the extension system for content scripts: http://code.google.com/chrome/extensions/content_scripts.html#execution-environment Essentially, they help protect an extension's content script from getting confused by the page manipulating it's JavaScript environment. > Isolated worlds point to the same underlying native DOM objects - so that > DOM changes made in isolated world 'A' will be visible in isolated world 'B' Yes. > - even if the DOM wrappers have been tweaked in 'B'. That's right. The properties of the DOM objects captured by the various DOM Core, etc, specs are identical in the two worlds. > Is there a way to only > make part of the native DOM tree accessible to a isolated world? Not in our current implementation, but you could imagine doing that in the future. For the content scripts application, the content script has strictly greater privileges than the page it's running on. One way to think about that is that code in the isolated world can add a <script> tag to the document, which runs on the main world, just like what would happen if Python interacting with the DOM added a <script> tag. Adam > On Mon, Jan 11, 2010 at 6:49 AM, Adam Barth <abarth-mozilla at adambarth.com> > wrote: >> >> [Re-sending now that I've subscribed with this address] >> >> I haven't been following this module discussion very closely, but >> these recent comments sound related to something we've been playing >> around with in WebKit. We have a mechanism (called an "isolated >> world") that lets multiple JavaScript contexts share access to the >> same DOM without ever exchanging JavaScript pointers with each other. >> Essentially: >> >> 1) Each world gets it's own global object, complete with independent, >> mutable built-in objects. >> 2) Each world gets it's own set of (mutable) DOM wrappers. >> >> For those not familiar with the details of browser implementations, >> JavaScript DOM objects are usually implemented as wrapper objects >> around the "native" object, implemented in C++. Because each isolated >> world gets its own wrappers, the usual one-to-one relation between the >> native objects and it's wrapper is replaced with a one-to-many >> relation. >> >> This trick works nicely because DOM is a language-neutral interface. >> Just like you can have Python and JavaScript bindings for the DOM, >> isolated worlds essentially lets you have JavaScriptA and JavaScriptB >> bindings. The key invariant is that two worlds never exchange >> JavaScript pointers (which you can think of as object-capabilities, if >> you like), just like Python and JavaScript would never exchange >> pointers if they interacted with the same DOM objects. >> >> I'm not sure this mechanism is directly applicable to future versions >> of ECMAScript because we're able to implement it just fine using ES5. >> However, it might be an approach worth considering in designing a >> module system for ECMAScript. >> >> Adam >> >> >> On Sun, Jan 10, 2010 at 9:38 PM, Brendan Eich <brendan at mozilla.com> wrote: >> > On Jan 10, 2010, at 9:30 PM, David-Sarah Hopwood wrote: >> > >> >> Brendan Eich wrote: >> >>> >> >>> On Jan 10, 2010, at 1:14 AM, Kevin Curtis wrote: >> >>> >> >>>> From SecureEcmaScript proposal: >> >>>> 6. The top level binding of this in an evaled Program is not the >> >>>> global object, but rather a frozen root object containing just the >> >>>> globals defined in the ES5 spec. >> >>> >> >>> For many current applications, the frozen |this| object is not >> >>> necessary >> >>> or desirable in global code. The essential characteristic of modules, >> >>> isolation for each module's "inside" from unimported effects of other >> >>> modules, does not necessarily mean no mutation of primordial objects. >> >> >> >> On the contrary, it does necessarily mean that. If you can mutate >> >> primordial objects, then there is no isolation of any module. There >> >> may be a reduction in the possibilities for accidental interference >> >> between modules, but that should be distinguished from isolation. >> > >> > Who said primordial objects are shared between modules? You assume too >> > much >> > in assuming your favored conclusion. >> > >> > There are three things a module has to deal with to interact with JS in >> > browsers: >> > >> > 1. The global object and its Object, Date, etc. primordials. >> > 2. The |this| binding for "global" code in the module, at the module's >> > top >> > level. >> > 3. The scope chain tail object, the only object on the scope chain for >> > global code in ES1-5. >> > >> > These are not necessarily the same at all. The lexical_scope proposal >> > eliminates 3 by making the top-level a lexical environment, not an >> > object. >> > The |this| binding may or may not refer to the global object. And it's >> > not >> > settled whether, in browsers with many global objects (one per >> > window/frame/iframe) there is only one global among N>1 modules, or a >> > global >> > per module. >> > >> > If modules do not use free variables, only what they import, then you're >> > wrong that isolation requires freezing. Modules could use their own >> > primordials, or none (only library code, possibly better versions of >> > Date, >> > etc.). The object and array initialisers and regexp literals would have >> > to >> > construct using some "original value" of Object, Array, RegExp. But not >> > necessarily a frozen one, if per-module. >> > >> > That you conflate frozen primordials with isolation is exactly the kind >> > of >> > over-specification through shortest-path evolution of ES5 to which I >> > object. >> > It is not going to fly in TC39 among all the browser vendors. We need to >> > hear from Apple, Microsoft, and Opera, but I'm already objecting to this >> > kind of axiom planting. Let's back up and talk about modules from >> > premises >> > forward. >> > >> > /be >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss > >
Isolated worlds could be useful for Secure EcmaScript (SES). That is SES could have a "world" with primordials and DOM bindings/wrappers configured for security. There would be no interaction between scripts in the "application/ecmascript" and "application/ses" worlds. e.g.
<html><head> <script type="application/ses"> window.x = 4; </script>
<script type="application/ecmascript"> if (window.x == 4) { alert("Cannot be true -- window.x was set in the SES isolated world!!!"); } </script> </head> ...
Of course, changes to the underlying 'native' DOM would be visible between the EcmaScript and SES worlds. A div added to the DOM in the EcmaScript world would be visible in the SES world.
Isolated worlds could be useful for Secure EcmaScript (SES). That is SES could have a "world" with primordials and DOM bindings/wrappers configured for security. There would be no interaction between scripts in the "application/ecmascript" and "application/ses" worlds. e.g. <html><head> <script type="application/ses"> window.x = 4; </script> <script type="application/ecmascript"> if (window.x == 4) { alert("Cannot be true -- window.x was set in the SES isolated world!!!"); } </script> </head> ... Of course, changes to the underlying 'native' DOM would be visible between the EcmaScript and SES worlds. A div added to the DOM in the EcmaScript world would be visible in the SES world. On Mon, Jan 11, 2010 at 6:49 AM, Adam Barth <abarth-mozilla at adambarth.com>wrote: > [Re-sending now that I've subscribed with this address] > > I haven't been following this module discussion very closely, but > these recent comments sound related to something we've been playing > around with in WebKit. We have a mechanism (called an "isolated > world") that lets multiple JavaScript contexts share access to the > same DOM without ever exchanging JavaScript pointers with each other. > Essentially: > > 1) Each world gets it's own global object, complete with independent, > mutable built-in objects. > 2) Each world gets it's own set of (mutable) DOM wrappers. > > For those not familiar with the details of browser implementations, > JavaScript DOM objects are usually implemented as wrapper objects > around the "native" object, implemented in C++. Because each isolated > world gets its own wrappers, the usual one-to-one relation between the > native objects and it's wrapper is replaced with a one-to-many > relation. > > This trick works nicely because DOM is a language-neutral interface. > Just like you can have Python and JavaScript bindings for the DOM, > isolated worlds essentially lets you have JavaScriptA and JavaScriptB > bindings. The key invariant is that two worlds never exchange > JavaScript pointers (which you can think of as object-capabilities, if > you like), just like Python and JavaScript would never exchange > pointers if they interacted with the same DOM objects. > > I'm not sure this mechanism is directly applicable to future versions > of ECMAScript because we're able to implement it just fine using ES5. > However, it might be an approach worth considering in designing a > module system for ECMAScript. > > Adam > > > On Sun, Jan 10, 2010 at 9:38 PM, Brendan Eich <brendan at mozilla.com> wrote: > > On Jan 10, 2010, at 9:30 PM, David-Sarah Hopwood wrote: > > > >> Brendan Eich wrote: > >>> > >>> On Jan 10, 2010, at 1:14 AM, Kevin Curtis wrote: > >>> > >>>> From SecureEcmaScript proposal: > >>>> 6. The top level binding of this in an evaled Program is not the > >>>> global object, but rather a frozen root object containing just the > >>>> globals defined in the ES5 spec. > >>> > >>> For many current applications, the frozen |this| object is not > necessary > >>> or desirable in global code. The essential characteristic of modules, > >>> isolation for each module's "inside" from unimported effects of other > >>> modules, does not necessarily mean no mutation of primordial objects. > >> > >> On the contrary, it does necessarily mean that. If you can mutate > >> primordial objects, then there is no isolation of any module. There > >> may be a reduction in the possibilities for accidental interference > >> between modules, but that should be distinguished from isolation. > > > > Who said primordial objects are shared between modules? You assume too > much > > in assuming your favored conclusion. > > > > There are three things a module has to deal with to interact with JS in > > browsers: > > > > 1. The global object and its Object, Date, etc. primordials. > > 2. The |this| binding for "global" code in the module, at the module's > top > > level. > > 3. The scope chain tail object, the only object on the scope chain for > > global code in ES1-5. > > > > These are not necessarily the same at all. The lexical_scope proposal > > eliminates 3 by making the top-level a lexical environment, not an > object. > > The |this| binding may or may not refer to the global object. And it's > not > > settled whether, in browsers with many global objects (one per > > window/frame/iframe) there is only one global among N>1 modules, or a > global > > per module. > > > > If modules do not use free variables, only what they import, then you're > > wrong that isolation requires freezing. Modules could use their own > > primordials, or none (only library code, possibly better versions of > Date, > > etc.). The object and array initialisers and regexp literals would have > to > > construct using some "original value" of Object, Array, RegExp. But not > > necessarily a frozen one, if per-module. > > > > That you conflate frozen primordials with isolation is exactly the kind > of > > over-specification through shortest-path evolution of ES5 to which I > object. > > It is not going to fly in TC39 among all the browser vendors. We need to > > hear from Apple, Microsoft, and Opera, but I'm already objecting to this > > kind of axiom planting. Let's back up and talk about modules from > premises > > forward. > > > > /be > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20100206/adafac4a/attachment.html>
[Re-sending now that I've subscribed with this address]
I haven't been following this module discussion very closely, but these recent comments sound related to something we've been playing around with in WebKit. We have a mechanism (called an "isolated world") that lets multiple JavaScript contexts share access to the same DOM without ever exchanging JavaScript pointers with each other. Essentially:
For those not familiar with the details of browser implementations, JavaScript DOM objects are usually implemented as wrapper objects around the "native" object, implemented in C++. Because each isolated world gets its own wrappers, the usual one-to-one relation between the native objects and it's wrapper is replaced with a one-to-many relation.
This trick works nicely because DOM is a language-neutral interface. Just like you can have Python and JavaScript bindings for the DOM, isolated worlds essentially lets you have JavaScriptA and JavaScriptB bindings. The key invariant is that two worlds never exchange JavaScript pointers (which you can think of as object-capabilities, if you like), just like Python and JavaScript would never exchange pointers if they interacted with the same DOM objects.
I'm not sure this mechanism is directly applicable to future versions of ECMAScript because we're able to implement it just fine using ES5. However, it might be an approach worth considering in designing a module system for ECMAScript.
Adam