Re: Dynamically changing of loader global

2012-12-28 Thread David Herman
On Dec 26, 2012, at 3:03 PM, David Bruant  wrote:

>> The initial value. We can look into what it would mean to make it 
>> modifiable, but we'd probably not make that the API; we'd probably just have 
>> a setter.
> Good point.
> [Adding MarkM into the mix for this part]
> I wish to point out a potential security/convenience issue regarding 
> inherited getter/setters. My point is broader than the 'global' loader 
> situation (it includes everything covered by WebIDL for instance), but let's 
> assume a 'global' setter is added to Loader.prototype and I'll draw the 
> general conclusion from this example.
> If I want to share a single loader instance to someone else, but not provide 
> access to the loader global, I have to delete Loader.prototype.global 
> (otherwise, someone can extract the getter and use the reference to the 
> loader instance to retrieve the global)

Heh, good luck with that. A loader is a very high privilege object. Just 
removing the getter is not going to help you, when you can easily write

loader.eval("this")

For security, it's much better to treat a loader is a super-powerful object, 
and completely deny access to it to untrusted code. That's one of the reasons 
why there's no f.getLoader() or getCurrentLoader() API. The System object is a 
loader, but when you create a sandbox, you would typically censor or attenuate 
its power.

Dave

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


WebIDL attribute reflection (was: Dynamically changing of loader global)

2012-12-28 Thread David Bruant

Le 28/12/2012 09:23, Brendan Eich a écrit :
The trade-off is not between own data properties and shared 
prototype-homed accessors.


Rather, it is between own and inherited accessors.
True. The reason is that WebIDL attributes have types that need to be 
enforced [1] among other things.


In either case, one needs per-instance state, often stored in a 
peer-to-JS C++ DOM native data structure that must exist whether 
there' s a JS reflection.


But with own accessors, one also then needs another slot or pair of 
slots (for setter and getter).
These could be created lazily on Object.getOwnPropertyDescriptor or 
Object.defineProperty calls, no?


It's not enough to make a magic data property with code backing it to 
compute or normalize or commit other effects on get and/or set. We 
can't model magic own data properties that involve computed get/set in 
WebIDL or ES5 (or ES6, outside of proxies).

Proxies sound like an interesting option to explore.
An ES6 proxy-based implementation could have own data properties and 
perform the type checks/coercion as necessary. Reflecting as own 
properties may also simplify the WebIDL attributes getter/setter 
algorithms, at least by removing the checks on |this| (since 
getter/setters couldn't be extracted anymore).

As you say, the per-instance storage would be exactly the same.


So economics come in, and shared accessors win big-time on efficiency.

The key insight is that the per-instance storage does not change 
between alternative own vs. inherited accessor scenarios, but own adds 
extra slots to every instance. That hurts.


Pre-WebIDL DOM bindings cheat by using native code to run on every set 
and even get, without the own data property reflecting as an accessor. 
That seems worse than what we have settled on with prototype-homed 
inherited accessors, no?
I'm not 100% sure. In a world with proxies, "code to run on every set 
and even get without the own data property reflecting as an accessor" 
will be legion; that's almost the definition of a proxy.
As long as WebIDL properly defines the semantics of this code, I don't 
see the problem. This joins Allen's recent point about exotic objects 
having to properly specify their semantics [2]


What was bad with the native code run on get/set was that the behavior 
was unspec'ed and non-interoperable between implementations. If WebIDL 
fills the gap, things become much better.


Using ES6 proxies semantics to explain own data properties in WebIDL would:
* be neutral when it comes to storage
* simplify the getter/setter attributes algorithms (remove |this| 
checks, maybe other things due to non-extractability)

* solve the ocaps API issue
* solve the convenience issues raised by Brandon

The balance looks positive to me.

David

[1] http://dev.w3.org/2006/webapi/WebIDL/#es-attributes
[2] last paragraph of 
https://mail.mozilla.org/pipermail/es-discuss/2012-December/027224.html

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-28 Thread Brendan Eich
The trade-off is not between own data properties and shared 
prototype-homed accessors.


Rather, it is between own and inherited accessors.

In either case, one needs per-instance state, often stored in a 
peer-to-JS C++ DOM native data structure that must exist whether there' 
s a JS reflection.


But with own accessors, one also then needs another slot or pair of 
slots (for setter and getter).


It's not enough to make a magic data property with code backing it to 
compute or normalize or commit other effects on get and/or set. We can't 
model magic own data properties that involve computed get/set in WebIDL 
or ES5 (or ES6, outside of proxies).


So economics come in, and shared accessors win big-time on efficiency.

The key insight is that the per-instance storage does not change between 
alternative own vs. inherited accessor scenarios, but own adds extra 
slots to every instance. That hurts.


Pre-WebIDL DOM bindings cheat by using native code to run on every set 
and even get, without the own data property reflecting as an accessor. 
That seems worse than what we have settled on with prototype-homed 
inherited accessors, no?


/be

Mark S. Miller wrote:

So does anyone know why? Own properties were the obvious choice, so
there must have been some reason to choose inherited accessors
instead.

On Thu, Dec 27, 2012 at 11:32 AM, Brandon Benvie
  wrote:

It's definitely been my experience that accessors, as found in IE and
Firefox, are much more fidgety and error prone than own data properties, as
found in WebKit. The fact that it becomes possible to call them on invalid
targets and that it's no longer possible for a debugger to simply display
own properties exacerbates this fidgetyness. Even worse, the prototypes
which the accessors live on are themselves not valid targets, which
basically invites errors.





___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-27 Thread Mark S. Miller
So does anyone know why? Own properties were the obvious choice, so
there must have been some reason to choose inherited accessors
instead.

On Thu, Dec 27, 2012 at 11:32 AM, Brandon Benvie
 wrote:
> It's definitely been my experience that accessors, as found in IE and
> Firefox, are much more fidgety and error prone than own data properties, as
> found in WebKit. The fact that it becomes possible to call them on invalid
> targets and that it's no longer possible for a debugger to simply display
> own properties exacerbates this fidgetyness. Even worse, the prototypes
> which the accessors live on are themselves not valid targets, which
> basically invites errors.



-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-27 Thread Brandon Benvie
It's definitely been my experience that accessors, as found in IE and
Firefox, are much more fidgety and error prone than own data properties, as
found in WebKit. The fact that it becomes possible to call them on invalid
targets and that it's no longer possible for a debugger to simply display
own properties exacerbates this fidgetyness. Even worse,
the prototypes which the accessors live on are themselves not valid
targets, which basically invites errors.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-27 Thread David Bruant

Le 27/12/2012 20:04, Mark S. Miller a écrit :
This is a very good point. Is there any reason other than legacy 
compat why WebIDL specifies inherited accessors rather than own 
properties?
There is no legacy compat issue. Before WebIDL, the ECMAScript 
representation of DOM objects was an absurd under-specified and 
consequently non-interoperable mess.
We are still in this mess. IE9 is following WebIDL quite closely. I 
assume IE10 is doing better (I've never had a look, but Microsoft is 
following a good path, so I assume progress). All other browsers are 
still very far from WebIDL. Firefox is making fast progress [1]. I don't 
think I have seen progress in other browsers, but I haven't been 
following that closely either.


I don't know why inherited accessors were chosen, but I'm very 
interested in learning if someone has the answer. Since we can decently 
assume than no web content really relies on WebIDL, there is certainly 
still time to change WebIDL if necessary


David

[1] https://bugzilla.mozilla.org/show_bug.cgi?id=580070
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-27 Thread Mark S. Miller
On Wed, Dec 26, 2012 at 3:03 PM, David Bruant  wrote:
> Le 26/12/2012 23:14, David Herman a écrit :
>
>> On Dec 24, 2012, at 2:34 PM, David Bruant  wrote:
>>
>>> I've reading the loader API [1] and I was wondering if it was possible to
>>> dynamically change the global. I think it is by doing the following, but
>>> tell me if I'm wrong:
>>
>> That wasn't the intention. It probably wasn't written out since the full
>> semantics isn't spelled out yet (though Sam and I have been making good
>> progress working through the details of the semantics), but the idea was
>> that the properties of the options object are read in up-front and stored
>> internally. The getter always returns that internally closed-over value that
>> was obtained when the loader was first created.
>
> Ok, thanks for the clarification. The strawman as it was didn't explain the
> full semantics hence my question.
>
>
>>> In other words, in the global in the loader the initial or the dynamic
>>> value of the "global" option?
>>
>> The initial value. We can look into what it would mean to make it
>> modifiable, but we'd probably not make that the API; we'd probably just have
>> a setter.
>
> Good point.
> [Adding MarkM into the mix for this part]
> I wish to point out a potential security/convenience issue regarding
> inherited getter/setters. My point is broader than the 'global' loader
> situation (it includes everything covered by WebIDL for instance), but let's
> assume a 'global' setter is added to Loader.prototype and I'll draw the
> general conclusion from this example.
> If I want to share a single loader instance to someone else, but not provide
> access to the loader global, I have to delete Loader.prototype.global
> (otherwise, someone can extract the getter and use the reference to the
> loader instance to retrieve the global)
> The problem with deleting Loader.prototype.global is that it's deleted for
> every single instance which in turns make the code harder to write (because,
> defensively, one needs to extract the getter/setter pair an then use that
> instead of the more convenient "myLoader.global" syntax). The opposite way,
> if freezing Loader.prototype, it becomes *impossible* to revoke the
> capability to introspect instances using the inherited getters/setters.
>
> In essence, an inherited accessor means that the choice allowing access to a
> given property isn't a per-instance choice anymore. It's a per-"class"
> choice (keep it or remove it for every instance) which is probably fine for
> most situations, but certainly too coarse for some others.

This is a very good point. Is there any reason other than legacy
compat why WebIDL specifies inherited accessors rather than own
properties?


>
> Since the amount of storage is equivalent anyway (you need some sort of
> private property to associate the global to the loader instance), I would
> suggest to go to an own "global" data property for loaders... and I guess to
> stay away from inherited accessors when describing a per-instance property
> for the reasons I described.
>
> David



--
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-26 Thread David Bruant

Le 26/12/2012 23:14, David Herman a écrit :

On Dec 24, 2012, at 2:34 PM, David Bruant  wrote:


I've reading the loader API [1] and I was wondering if it was possible to 
dynamically change the global. I think it is by doing the following, but tell 
me if I'm wrong:

That wasn't the intention. It probably wasn't written out since the full 
semantics isn't spelled out yet (though Sam and I have been making good 
progress working through the details of the semantics), but the idea was that 
the properties of the options object are read in up-front and stored 
internally. The getter always returns that internally closed-over value that 
was obtained when the loader was first created.
Ok, thanks for the clarification. The strawman as it was didn't explain 
the full semantics hence my question.



In other words, in the global in the loader the initial or the dynamic value of the 
"global" option?

The initial value. We can look into what it would mean to make it modifiable, 
but we'd probably not make that the API; we'd probably just have a setter.

Good point.
[Adding MarkM into the mix for this part]
I wish to point out a potential security/convenience issue regarding 
inherited getter/setters. My point is broader than the 'global' loader 
situation (it includes everything covered by WebIDL for instance), but 
let's assume a 'global' setter is added to Loader.prototype and I'll 
draw the general conclusion from this example.
If I want to share a single loader instance to someone else, but not 
provide access to the loader global, I have to delete 
Loader.prototype.global (otherwise, someone can extract the getter and 
use the reference to the loader instance to retrieve the global)
The problem with deleting Loader.prototype.global is that it's deleted 
for every single instance which in turns make the code harder to write 
(because, defensively, one needs to extract the getter/setter pair an 
then use that instead of the more convenient "myLoader.global" syntax). 
The opposite way, if freezing Loader.prototype, it becomes *impossible* 
to revoke the capability to introspect instances using the inherited 
getters/setters.


In essence, an inherited accessor means that the choice allowing access 
to a given property isn't a per-instance choice anymore. It's a 
per-"class" choice (keep it or remove it for every instance) which is 
probably fine for most situations, but certainly too coarse for some others.


Since the amount of storage is equivalent anyway (you need some sort of 
private property to associate the global to the loader instance), I 
would suggest to go to an own "global" data property for loaders... and 
I guess to stay away from inherited accessors when describing a 
per-instance property for the reasons I described.


David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-26 Thread David Herman
On Dec 24, 2012, at 2:34 PM, David Bruant  wrote:

> I've reading the loader API [1] and I was wondering if it was possible to 
> dynamically change the global. I think it is by doing the following, but tell 
> me if I'm wrong:

That wasn't the intention. It probably wasn't written out since the full 
semantics isn't spelled out yet (though Sam and I have been making good 
progress working through the details of the semantics), but the idea was that 
the properties of the options object are read in up-front and stored 
internally. The getter always returns that internally closed-over value that 
was obtained when the loader was first created.

> In other words, in the global in the loader the initial or the dynamic value 
> of the "global" option?

The initial value. We can look into what it would mean to make it modifiable, 
but we'd probably not make that the API; we'd probably just have a setter.

> If it was the dynamic value, I think it would help a lot in the document.open 
> situation [2]
> 
> David
> 
> [1] http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders#loader_api
> [2] http://lists.w3.org/Archives/Public/www-dom/2012OctDec/0166.html

Thanks, I'll read up on this.

Dave

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-26 Thread David Bruant

Le 25/12/2012 23:01, Brandon Benvie a écrit :
I updated my Loader implementation to allow dynamically modifying the 
options since it seems like a potentially good idea worth 
investigating, and also seems like it might be indicated as the 
desired functionality based on global and baseURL being specified as 
getters.
That's what I thought too, though a getter may just be for better 
syntax. A "getGlobal" method would be of bad taste in a post-ES5 world.


In order to make this work requires storing a reference to the parent 
as well in order to keep the spirit of deferring to the parent when 
the loader's options don't specify a global. You can see this in 
action here 
https://github.com/Benvie/continuum/blob/gh-pages/engine/builtins/%40system.js#L63. 



For good measure I made this work with most of the options, not just 
loader and baseURL (the three callbacks).

Really cool, thanks :-)

On a related note, I had misunderstood document.open on the www-dom 
thread, so what I suggested here can't be a solution, I think. However, 
I'm glad it caught your attention enough to think it's a valuable idea :-)


David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-25 Thread Brandon Benvie
I updated my Loader implementation to allow dynamically modifying the
options since it seems like a potentially good idea worth investigating,
and also seems like it might be indicated as the desired functionality
based on global and baseURL being specified as getters. In order to make
this work requires storing a reference to the parent as well in order to
keep the spirit of deferring to the parent when the loader's options don't
specify a global. You can see this in action here
https://github.com/Benvie/continuum/blob/gh-pages/engine/builtins/%40system.js#L63
.

For good measure I made this work with most of the options, not just loader
and baseURL (the three callbacks).

Unfortunately github has been failing to build the gh-pages for a few days
now so until I can diagnose the reason for it randomly deciding to fail
these changes aren't reflected in the live debugger demo hosted at github.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-25 Thread Brandon Benvie
Oh I see more clearly now what you mean. The proposal leaves room for
options.global to be dynamically changed and have that reflected in
modules, since it's specified as an accessor. My presumption would be that
if that were allowed, it wouldn't actually change the global object for
modules that loader has already loaded, since they would have already
created a Global Environment Record using the global at the time of
initialization. But it would allow for newly loaded modules to reference a
different global.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-24 Thread David Bruant
For that matter, you've implemented the "initial" solution in continuum 
[1] because you look at options.global when constructing the loader, but 
never look at it ever after.


By the way, maybe you should Object-wrap it or throw if it isn't an 
object? The proposal doesn't say which should occur.


David

[1] 
https://github.com/Benvie/continuum/blob/6338e3cdfc5a472d0998a6343ed38d5dc31e454c/engine/builtins/%40system.js#L50


Le 24/12/2012 23:37, Brandon Benvie a écrit :
To clarify: are you asking if an arbitrary object is a valid global 
object when using a custom loader? If not, then I have a lot of code 
to rewrite.



On Mon, Dec 24, 2012 at 5:34 PM, David Bruant > wrote:


Hi,

I've reading the loader API [1] and I was wondering if it was
possible to dynamically change the global. I think it is by doing
the following, but tell me if I'm wrong:

const options = {
global : {
changeGlobal: function(g){
options.global = g;
}
}
}

var l = new Loader(Loader, options);

l.eval('changeGlobal({a:37}); console.log(a);');

In other words, in the global in the loader the initial or the
dynamic value of the "global" option?
If it was the dynamic value, I think it would help a lot in the
document.open situation [2]

David

[1]
http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders#loader_api
[2] http://lists.w3.org/Archives/Public/www-dom/2012OctDec/0166.html
___
es-discuss mailing list
es-discuss@mozilla.org 
https://mail.mozilla.org/listinfo/es-discuss




___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-24 Thread David Bruant

Le 24/12/2012 23:37, Brandon Benvie a écrit :
To clarify: are you asking if an arbitrary object is a valid global 
object when using a custom loader? If not, then I have a lot of code 
to rewrite.

What I'm asking is:
"is the global in the loader the initial or the dynamic value of the 
"global" option?"

If dynamic value, my snippet will log "37".
If initial value, my snippet will throw a ReferenceError originating 
from the eval-ed script (because there is no "a" global in the initial 
global)


I assume any object can be used as a global in a loader. I see no 
restriction in the proposal.


David




On Mon, Dec 24, 2012 at 5:34 PM, David Bruant > wrote:


Hi,

I've reading the loader API [1] and I was wondering if it was
possible to dynamically change the global. I think it is by doing
the following, but tell me if I'm wrong:

const options = {
global : {
changeGlobal: function(g){
options.global = g;
}
}
}

var l = new Loader(Loader, options);

l.eval('changeGlobal({a:37}); console.log(a);');

In other words, in the global in the loader the initial or the
dynamic value of the "global" option?
If it was the dynamic value, I think it would help a lot in the
document.open situation [2]

David

[1]
http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders#loader_api
[2] http://lists.w3.org/Archives/Public/www-dom/2012OctDec/0166.html
___
es-discuss mailing list
es-discuss@mozilla.org 
https://mail.mozilla.org/listinfo/es-discuss




___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-24 Thread Brandon Benvie
I meant, if the answer to your question is "no". =/


On Mon, Dec 24, 2012 at 5:37 PM, Brandon Benvie
wrote:

> To clarify: are you asking if an arbitrary object is a valid global object
> when using a custom loader? If not, then I have a lot of code to rewrite.
>
>
> On Mon, Dec 24, 2012 at 5:34 PM, David Bruant  wrote:
>
>> Hi,
>>
>> I've reading the loader API [1] and I was wondering if it was possible to
>> dynamically change the global. I think it is by doing the following, but
>> tell me if I'm wrong:
>>
>> const options = {
>> global : {
>> changeGlobal: function(g){
>> options.global = g;
>> }
>> }
>> }
>>
>> var l = new Loader(Loader, options);
>>
>> l.eval('changeGlobal({a:37}); console.log(a);');
>>
>> In other words, in the global in the loader the initial or the dynamic
>> value of the "global" option?
>> If it was the dynamic value, I think it would help a lot in the
>> document.open situation [2]
>>
>> David
>>
>> [1] http://wiki.ecmascript.org/**doku.php?id=harmony:module_**
>> loaders#loader_api
>> [2] 
>> http://lists.w3.org/Archives/**Public/www-dom/2012OctDec/**0166.html
>> __**_
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/**listinfo/es-discuss
>>
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Dynamically changing of loader global

2012-12-24 Thread Brandon Benvie
To clarify: are you asking if an arbitrary object is a valid global object
when using a custom loader? If not, then I have a lot of code to rewrite.


On Mon, Dec 24, 2012 at 5:34 PM, David Bruant  wrote:

> Hi,
>
> I've reading the loader API [1] and I was wondering if it was possible to
> dynamically change the global. I think it is by doing the following, but
> tell me if I'm wrong:
>
> const options = {
> global : {
> changeGlobal: function(g){
> options.global = g;
> }
> }
> }
>
> var l = new Loader(Loader, options);
>
> l.eval('changeGlobal({a:37}); console.log(a);');
>
> In other words, in the global in the loader the initial or the dynamic
> value of the "global" option?
> If it was the dynamic value, I think it would help a lot in the
> document.open situation [2]
>
> David
>
> [1] http://wiki.ecmascript.org/**doku.php?id=harmony:module_**
> loaders#loader_api
> [2] 
> http://lists.w3.org/Archives/**Public/www-dom/2012OctDec/**0166.html
> __**_
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/**listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Dynamically changing of loader global

2012-12-24 Thread David Bruant

Hi,

I've reading the loader API [1] and I was wondering if it was possible 
to dynamically change the global. I think it is by doing the following, 
but tell me if I'm wrong:


const options = {
global : {
changeGlobal: function(g){
options.global = g;
}
}
}

var l = new Loader(Loader, options);

l.eval('changeGlobal({a:37}); console.log(a);');

In other words, in the global in the loader the initial or the dynamic 
value of the "global" option?
If it was the dynamic value, I think it would help a lot in the 
document.open situation [2]


David

[1] http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders#loader_api
[2] http://lists.w3.org/Archives/Public/www-dom/2012OctDec/0166.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss