archives

« Bugzilla Issues Index

#1898 — Provide separation of global this and global object


Currently HTML overrides ES to say that this is WindowProxy whereas the global object is Window. If this is made configurable for realms we'd have one less issue there.

Related to bug 78 per Brendan.


The latest draft adds the ability to pass a proxy target and handler into the Realm constructor. If that is done, a proxy is created as the global object instead of a normal object. Is that enough to cover the requirements here, or is a WindowProxy sufficiently different from an ES Proxy that more is needed?


Ian or Boris may be able to answer that question.


Figuring out the answer to the question in comment 1 does seem important before we declare all this stable.


OK I educated myself. Here's the gist of it: a single frame can navigate from one page to another, and those pages can call each others' global functions, even if some of the pages are not the active page in the frame. All of those pages actually have the *same* (===) global `this` object, which acts like a proxy to whatever the current active page in the frame is. But unbound variables are always interpreted relative to the page they came from. So calling a function on an inactive page can get divergent behavior between the global `this` and global variables. Here's an example:

https://gist.github.com/dherman/82ca22b2ecc506d01182

The current realm API is almost sufficient to reflect all this, except that it doesn't let you specify a distinct `this` object. I think the fix here is, basically as Anne says, to allow you to independently specify a second object that acts as the global `this`. Currently the Realm constructor takes unnamed optional arguments for creating a global proxy, and we now need an optional `this` object (which should default to whatever the global object is), so I think we probably need to go back to named arguments, something like:

new Realm({
target: globalProxyTarget,
handler: globalProxyHandler,
this: globalThis
})

AFAICT the only implication this degree of flexibility has for engine implementations is that global `this` (which is trivially statically recognizable) gets pointed to a different object, so I don't think it should cause any implementation difficulties.

Dave


(In reply to comment #4)
> OK I educated myself. Here's the gist of it: a single frame can navigate from
> one page to another, and those pages can call each others' global functions,
> even if some of the pages are not the active page in the frame. All of those
> pages actually have the *same* (===) global `this` object, which acts like a
> proxy to whatever the current active page in the frame is. But unbound
> variables are always interpreted relative to the page they came from. So
> calling a function on an inactive page can get divergent behavior between the
> global `this` and global variables. Here's an example:

To clarify, are you saying that:

var activePageObj = new this.Object;//creates a new object
// in the Realm of active page

var currentFrameObj = new Object; //create a new object
// in the Realm of the current frame


In other words, all global identifier bindings (including the default globals) are resolved using the Realm of the referencing code and that those bindings are not necessarily the same as the properties of the global this that is visible to that code.

Another example:

if ('foo' in this ===undefined) this.foo = "defined";
console.log(foo===undefined); //may be either true or false depending upon
//the relationship of globalThis and global env

>
>
> new Realm({
> target: globalProxyTarget,
> handler: globalProxyHandler,
> this: globalThis
> })
>
> AFAICT the only implication this degree of flexibility has for engine
> implementations is that global `this` (which is trivially statically
> recognizable) gets pointed to a different object, so I don't think it should
> cause any implementation difficulties.
>
> Dave

Note that RealmRecord (the spec. abstraction that backs Realm objects) http://people.mozilla.org/~jorendorff/es6-draft.html#table-20 already capture both a [[globalThis]] references and a [[globalEnv]] reference where [[globalEnv]] is GlobalEnvironmentReport that is used to capture and resolve global declarations from within the Realm.

However, [[globalEnv]] is currently always initialized (http://people.mozilla.org/~jorendorff/es6-draft.html#sec-setrealmglobalobj) to use the value of [[globalThis]] as the object component of the [[globalEnv]]. It sounds like that may need to changed.


deferred to ES7

The whole window/windowProxy thing...