Re: Converting an existing object to a proxy

2011-05-28 Thread LungZeno
On Sat, May 28, 2011 at 2:05 AM, Sean Eagan seaneag...@gmail.com wrote:
 On Fri, May 27, 2011 at 12:43 PM, Sean Eagan seaneag...@gmail.com wrote:
 Of course you could go the other way, and remove the default trap
 implementations.  All objects could have the same internal method
 implementation regardless of whether or not they are a proxy.  Within
 each internal method there could be a check as to whether the object
 is a proxy (has a [[Handler]]) AND has the trap, if so, it is invoked,
 otherwise the default pseudocode is performed.

 The pseudocode for checking if the object has a [[Handler]], and if
 that [[Handler]] has a trap, and then invoking the trap could all be
 factored out into a [[Trap]] (or something) internal method, which
 takes a trap name, and a list of arguments to pass to the trap, and
 returns whether or not the object has the trap, and if so, also a
 return value from the trap.  This would make for a very concise and
 clear spec with regard to proxies, and it would be relatively easy to
 update the current proposal to do this.

Another way, every object has a [[Proxify]] internal method
corresponding to Object.createFrom. Host objects have their
[[Proxify]] different to native objects. [[Proxify]] can also be
trapped w.r.t. invoking Proxy.createFrom(aProxy, handler, proto).

 Thanks,
 Sean Eagan
 ___
 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: Converting an existing object to a proxy

2011-05-27 Thread David Bruant

Le 27/05/2011 04:13, Mark S. Miller a écrit :
On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan cor...@cs.ucsc.edu 
mailto:cor...@cs.ucsc.edu wrote:


[documenting/expanding some ideas briefly discussed at today's
meeting]

The current proxy proposal has a method to create a new proxy:

var proxy = Proxy.create(handler, proto);

We could extend this proposal to allow an existing object to be
converted to a proxy, via:

var proxy = Proxy.createFrom(object, handler, proto);

I am surprised by this proposal since a design goal of proxies was to 
not be able to turn existing objects into proxies.

4th driving force of the proxy proposal:
security: avoid enabling arbitrary ES objects to be able to intercept 
the properties of another object


The API itself (Proxy.create, Proxy.createFunction) seems to have been 
design with this in mind.





Here, the return value 'proxy' is the same address as the argument
'object'.
The original object thus becomes a proxy. Any state of the
original object
is discarded.

The notion of object state is not defined anywhere in the ES5 spec. 
What is your definition of an object state ?




This extension appears to support additional applications, such as
registering an observer on an existing object. The target object would
first be cloned, then the target object would be converted into a
proxy that
dispatches to the cloned object, but which also notifies observers
about
accesses/updates to the (now proxified) object.


Is this the only use case?
If so, would it rather make sense to provide a specific Object event API 
for existing objects? It would allow to observe accesses/updates without 
turning the object into a proxy with arbitrary handler methods.





There are a number of open issues relating to security etc:
In particular, what objects can be proxified in this way - perhaps not
frozen object,
or objects with non-configurable properties or with unique names.


In today's meeting, I made two suggestions along these lines:

* Given the current proxy semantics, we should allow this only if the 
object-to-be-proxified is extensible and has no non-configurable own 
properties.
* We have on occasion discussed modifying the proxy proposal so that 
individual properties could be fixed rather than just the proxy as a 
whole. (Note: I am not in favor of such a change, but it could be done 
soundly.) Given that this change to proxies were done, then we should 
allow proxification only if the object-to-be-proxified is extensible, 
period.


In both cases, as you state, one effect of the operation is to remove 
all configurable own properties from the object. In both cases, we can 
adopt the rationale that the object-to-be-proxified could not have 
taken any action inconsistent with it always having been a proxy.


In both cases, we need the further restriction that it is a kind of 
object that can be emulated by a proxy. Today, this is technically 
only objects of [[Class]] Object or Function, but we're talking 
about relaxing that in any case.



A design goal is that for any object that could be proxified,
we can replace it with a proxy in a way that is semantically
transparent.

If you provide the ability to put any functions in the handler object, 
there in no such thing as semantically transparent. The handler 
methods can do whatever they wants; they are functions. Moreover with an 
API like Proxy.createFrom(object, handler, proto), the handler methods 
would need some help to initialize their internal proxy state in order 
to align with the object passed as argument.


Maybe that what you were suggesting was to use a forwarding handler by 
default as handler and to put the handler argument as this.target?


Even in this case, if creating proxies, an external user of the same 
object has no guarantee whatsoever of seeing no semantic difference 
since, for instance, any handler trap could throw an error when called.


My very first (mis)understanding of proxies was that they were an object 
access/update event API and that the handler functions were nice event 
handler. They are not. They are much more powerful. They are not an 
/addition/ to regular internal object methods. They are a /replacement/ 
of it.


However, I agree that an object event API is a valid use case (I have 
actually had a need for that a couple of days ago), but I don't think it 
should be a proxy extension. In my opinion, it should be its own 
library/API. Maybe implementable/standardizable with proxies + become 
internal function (see slide 56 at [1]), but its own thing.


I would be much more in favor of something like:

Object.observe(o, observers);

Observers would be an object that looks like a proxy handler called on 
every object interactions, but wouldn't be able to interact with the 
object internal methods. It would just be an addition to internal 
methods rather than a replacement 

Re: Converting an existing object to a proxy

2011-05-27 Thread Brendan Eich
On May 27, 2011, at 2:26 AM, David Bruant wrote:

 Le 27/05/2011 04:13, Mark S. Miller a écrit :
 
 On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan cor...@cs.ucsc.edu wrote:
 [documenting/expanding some ideas briefly discussed at today's meeting]
 
 The current proxy proposal has a method to create a new proxy:
 
 var proxy = Proxy.create(handler, proto);
 
 We could extend this proposal to allow an existing object to be
 converted to a proxy, via:
 
 var proxy = Proxy.createFrom(object, handler, proto);
 I am surprised by this proposal since a design goal of proxies was to not be 
 able to turn existing objects into proxies.
 4th driving force of the proxy proposal:
 security: avoid enabling arbitrary ES objects to be able to intercept the 
 properties of another object

That is not the same as avoid turning an object into a proxy, though.

The idea of permitting this becomes operation only for extensible objects 
with configurable properties is crucial.

The motivation is to unify ideas in proxies (in Harmony) with those proposed in 
http://wiki.ecmascript.org/doku.php?id=strawman:observe.

/be

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


Re: Converting an existing object to a proxy

2011-05-27 Thread Tom Van Cutsem
Since I gather this proposal is meant primarily to support observable
objects, two remarks:

1) Are proxies the appropriate building block performance-wise? From the
notes, it seems that current proxies are not a good building block because
of performance issues. Are the performance issues related to the membraning
needed for maintaining object identity, or are they more fundamental?

2) IIUC, one of the more interesting uses of observables would be to make
e.g. DOM nodes observable. That raises the issue of whether Proxy.createFrom
can be applied to Host objects, and of so, how to deal with built-in [[...]]
properties.

I tend to agree with David about having a separate observable API, if that
is indeed the driving use case. That API can be very similar to the Proxy
API though. Racket's chaperones come to mind: a chaperone is a strictly
less powerful kind of proxy, one that is not allowed to arbitrarily change
the result of the original operation (and IIRC, a chaperone also cannot stop
the original operation from taking place on the target object).

Cheers,
Tom

2011/5/27 David Bruant david.bru...@labri.fr

  Le 27/05/2011 04:13, Mark S. Miller a écrit :

 On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan cor...@cs.ucsc.eduwrote:

 [documenting/expanding some ideas briefly discussed at today's meeting]

 The current proxy proposal has a method to create a new proxy:

 var proxy = Proxy.create(handler, proto);

 We could extend this proposal to allow an existing object to be
 converted to a proxy, via:

 var proxy = Proxy.createFrom(object, handler, proto);

  I am surprised by this proposal since a design goal of proxies was to not
 be able to turn existing objects into proxies.
 4th driving force of the proxy proposal:
 security: avoid enabling arbitrary ES objects to be able to intercept the
 properties of another object

 The API itself (Proxy.create, Proxy.createFunction) seems to have been
 design with this in mind.




 Here, the return value 'proxy' is the same address as the argument
 'object'.
 The original object thus becomes a proxy. Any state of the original object
 is discarded.

  The notion of object state is not defined anywhere in the ES5 spec.
 What is your definition of an object state ?



 This extension appears to support additional applications, such as
 registering an observer on an existing object. The target object would
 first be cloned, then the target object would be converted into a proxy
 that
 dispatches to the cloned object, but which also notifies observers about
 accesses/updates to the (now proxified) object.

  Is this the only use case?
 If so, would it rather make sense to provide a specific Object event API
 for existing objects? It would allow to observe accesses/updates without
 turning the object into a proxy with arbitrary handler methods.




 There are a number of open issues relating to security etc:
 In particular, what objects can be proxified in this way - perhaps not
 frozen object,
 or objects with non-configurable properties or with unique names.


  In today's meeting, I made two suggestions along these lines:

  * Given the current proxy semantics, we should allow this only if the
 object-to-be-proxified is extensible and has no non-configurable own
 properties.
 * We have on occasion discussed modifying the proxy proposal so that
 individual properties could be fixed rather than just the proxy as a whole.
 (Note: I am not in favor of such a change, but it could be done soundly.)
 Given that this change to proxies were done, then we should allow
 proxification only if the object-to-be-proxified is extensible, period.

  In both cases, as you state, one effect of the operation is to remove all
 configurable own properties from the object. In both cases, we can adopt the
 rationale that the object-to-be-proxified could not have taken any action
 inconsistent with it always having been a proxy.

  In both cases, we need the further restriction that it is a kind of
 object that can be emulated by a proxy. Today, this is technically only
 objects of [[Class]] Object or Function, but we're talking about
 relaxing that in any case.



 A design goal is that for any object that could be proxified,
 we can replace it with a proxy in a way that is semantically transparent.

  If you provide the ability to put any functions in the handler object,
 there in no such thing as semantically transparent. The handler methods
 can do whatever they wants; they are functions. Moreover with an API like
 Proxy.createFrom(object, handler, proto), the handler methods would need
 some help to initialize their internal proxy state in order to align with
 the object passed as argument.

 Maybe that what you were suggesting was to use a forwarding handler by
 default as handler and to put the handler argument as this.target?

 Even in this case, if creating proxies, an external user of the same object
 has no guarantee whatsoever of seeing no semantic difference since, for
 

Re: Converting an existing object to a proxy

2011-05-27 Thread Tom Van Cutsem

 I tend to agree with David about having a separate observable API, if that
 is indeed the driving use case. That API can be very similar to the Proxy
 API though. Racket's chaperones come to mind: a chaperone is a strictly
 less powerful kind of proxy, one that is not allowed to arbitrarily change
 the result of the original operation (and IIRC, a chaperone also cannot stop
 the original operation from taking place on the target object).


Spoke too soon: from 
http://web.mit.edu/drracket_v501/share/racket/doc/reference/chaperones.html
I learn that chaperones can throw exceptions, and thus presumably abort an
intercepted operation early. Still, the idea of a tamed kind of proxy is
worth exploring.



 Cheers,
 Tom

 2011/5/27 David Bruant david.bru...@labri.fr

  Le 27/05/2011 04:13, Mark S. Miller a écrit :

 On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan cor...@cs.ucsc.eduwrote:

 [documenting/expanding some ideas briefly discussed at today's meeting]

 The current proxy proposal has a method to create a new proxy:

 var proxy = Proxy.create(handler, proto);

 We could extend this proposal to allow an existing object to be
 converted to a proxy, via:

 var proxy = Proxy.createFrom(object, handler, proto);

  I am surprised by this proposal since a design goal of proxies was to
 not be able to turn existing objects into proxies.
 4th driving force of the proxy proposal:
 security: avoid enabling arbitrary ES objects to be able to intercept the
 properties of another object

 The API itself (Proxy.create, Proxy.createFunction) seems to have been
 design with this in mind.




 Here, the return value 'proxy' is the same address as the argument
 'object'.
 The original object thus becomes a proxy. Any state of the original
 object
 is discarded.

  The notion of object state is not defined anywhere in the ES5 spec.
 What is your definition of an object state ?



 This extension appears to support additional applications, such as
 registering an observer on an existing object. The target object would
 first be cloned, then the target object would be converted into a proxy
 that
 dispatches to the cloned object, but which also notifies observers about
 accesses/updates to the (now proxified) object.

  Is this the only use case?
 If so, would it rather make sense to provide a specific Object event API
 for existing objects? It would allow to observe accesses/updates without
 turning the object into a proxy with arbitrary handler methods.




 There are a number of open issues relating to security etc:
 In particular, what objects can be proxified in this way - perhaps not
 frozen object,
 or objects with non-configurable properties or with unique names.


  In today's meeting, I made two suggestions along these lines:

  * Given the current proxy semantics, we should allow this only if the
 object-to-be-proxified is extensible and has no non-configurable own
 properties.
 * We have on occasion discussed modifying the proxy proposal so that
 individual properties could be fixed rather than just the proxy as a whole.
 (Note: I am not in favor of such a change, but it could be done soundly.)
 Given that this change to proxies were done, then we should allow
 proxification only if the object-to-be-proxified is extensible, period.

  In both cases, as you state, one effect of the operation is to remove
 all configurable own properties from the object. In both cases, we can adopt
 the rationale that the object-to-be-proxified could not have taken any
 action inconsistent with it always having been a proxy.

  In both cases, we need the further restriction that it is a kind of
 object that can be emulated by a proxy. Today, this is technically only
 objects of [[Class]] Object or Function, but we're talking about
 relaxing that in any case.



 A design goal is that for any object that could be proxified,
 we can replace it with a proxy in a way that is semantically transparent.

  If you provide the ability to put any functions in the handler object,
 there in no such thing as semantically transparent. The handler methods
 can do whatever they wants; they are functions. Moreover with an API like
 Proxy.createFrom(object, handler, proto), the handler methods would need
 some help to initialize their internal proxy state in order to align with
 the object passed as argument.

 Maybe that what you were suggesting was to use a forwarding handler by
 default as handler and to put the handler argument as this.target?

 Even in this case, if creating proxies, an external user of the same
 object has no guarantee whatsoever of seeing no semantic difference since,
 for instance, any handler trap could throw an error when called.

 My very first (mis)understanding of proxies was that they were an object
 access/update event API and that the handler functions were nice event
 handler. They are not. They are much more powerful. They are not an
 /addition/ to regular internal object methods. They are a /replacement/ of
 

Re: Converting an existing object to a proxy

2011-05-27 Thread David Bruant

Le 27/05/2011 11:35, Brendan Eich a écrit :

On May 27, 2011, at 2:26 AM, David Bruant wrote:


Le 27/05/2011 04:13, Mark S. Miller a écrit :
On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan cor...@cs.ucsc.edu 
mailto:cor...@cs.ucsc.edu wrote:


[documenting/expanding some ideas briefly discussed at today's
meeting]

The current proxy proposal has a method to create a new proxy:

var proxy = Proxy.create(handler, proto);

We could extend this proposal to allow an existing object to be
converted to a proxy, via:

var proxy = Proxy.createFrom(object, handler, proto);

I am surprised by this proposal since a design goal of proxies was to 
not be able to turn existing objects into proxies.

4th driving force of the proxy proposal:
security: avoid enabling arbitrary ES objects to be able to 
intercept the properties of another object


That is not the same as avoid turning an object into a proxy, though.
I actually thought that it's what it meant, but you're right. I think it 
should be clarify, because the way the API is design, it's quite clear 
that only new objects can be proxies. In the presentation you gave, it's 
clear that proxies can only go from trapping to fixed and that there 
is no way to go in the opposite direction


The idea of permitting this becomes operation only for extensible 
objects with configurable properties is crucial.
Is it? The first time I heard about the become operation was in the 
context of the proxy fix trap. Second time was this message. It doesn't 
sounds crucial yet to me.


The motivation is to unify ideas in proxies (in Harmony) with those 
proposed in http://wiki.ecmascript.org/doku.php?id=strawman:observe.

I hadn't read this proposal yet. Thanks.

I think that this discussion raises the following question:
Should all usages of the become operation be associated with proxies?

I would answer no because they sound like orthogonal concerns, but I'm 
interested in listening to arguments saying otherwise.


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


Re: Converting an existing object to a proxy

2011-05-27 Thread Sam Tobin-Hochstadt
On Fri, May 27, 2011 at 5:45 AM, Tom Van Cutsem tomvc...@gmail.com wrote:
 I tend to agree with David about having a separate observable API, if that
 is indeed the driving use case. That API can be very similar to the Proxy
 API though. Racket's chaperones come to mind: a chaperone is a strictly
 less powerful kind of proxy, one that is not allowed to arbitrarily change
 the result of the original operation (and IIRC, a chaperone also cannot stop
 the original operation from taking place on the target object).

 Spoke too soon: from
 http://web.mit.edu/drracket_v501/share/racket/doc/reference/chaperones.html
 I learn that chaperones can throw exceptions, and thus presumably abort an
 intercepted operation early. Still, the idea of a tamed kind of proxy is
 worth exploring.

I believe that the semantics of observers allow for throwing
exceptions, and thus terminating an operation, at least according to
the wiki page.
-- 
sam th
sa...@ccs.neu.edu
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Converting an existing object to a proxy

2011-05-27 Thread Boris Zbarsky

On 5/27/11 5:40 AM, Tom Van Cutsem wrote:

2) IIUC, one of the more interesting uses of observables would be to
make e.g. DOM nodes observable. That raises the issue of whether
Proxy.createFrom can be applied to Host objects, and of so, how to deal
with built-in [[...]] properties.


How useful would observables be for DOM nodes?

I guess you could notice expandos being added or removed, but that's 
about it, right?


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


Re: Converting an existing object to a proxy

2011-05-27 Thread Brendan Eich
On May 27, 2011, at 3:04 AM, David Bruant wrote:

 The idea of permitting this becomes operation only for extensible objects 
 with configurable properties is crucial.
 Is it? The first time I heard about the become operation was in the context 
 of the proxy fix trap. Second time was this message. It doesn't sounds 
 crucial yet to me.

The crucial applied to both only for extensible objects with configurable 
properties in that sentence. ;-)

The issue as I understand it is not becomes per se (more below), rather that an 
extensible object with configurable (own) properties could have those 
properties wrapped by accessors to emulate some of the intercessive power of 
proxies. From the security point of view, you want frozen and sealed objects, 
at least, to be immune to proxification because they are immune to such 
property-by-property wrapping with accessors, today.

See Mark's reply on the list dated 7:33pm yesterday.


 The motivation is to unify ideas in proxies (in Harmony) with those proposed 
 in http://wiki.ecmascript.org/doku.php?id=strawman:observe.
 I hadn't read this proposal yet. Thanks.
 
 I think that this discussion raises the following question:
 Should all usages of the become operation be associated with proxies?

We are not exposing becomes in the language -- certainly not for two arbitrary 
live objects.

In both the proxy fix case, and in this Proxy.createFrom case, one of the two 
objects is a newborn, not yet accessible. We brain-transplant between the 
accessible and inaccessible, swapping the objects' data. The identity is 
preserved but the internal and own properties are exchanged.

Questions about the proxify-existing-object case:

1. Won't the proxy want the original brain, the one transplanted into a 
newborn proxy (now become the regular object)?

2. Will the costs here be acceptable compared to something unstratified 
requiring no extra object, a la strawman:observe?

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


Re: Converting an existing object to a proxy

2011-05-27 Thread Sean Eagan
I think the separation between proxies and regular objects is too
much.  I would prefer to think of proxies as just a special kind of
object.  All objects could be thought of as having a handler (
[[Handler]] ), and proxy objects could be those objects whose
handler is an actual ES object as opposed to an abstract language
specification object.  This would be similar to the distinction
betweeen data and accessor properties, since you could think of a
default abstract [[Set]] and [[Get]] implementation for property
descriptors.  Then fixing a proxy object could just be thought of as
setting the object's [[Handler]] to an abstract specification handler,
and Proxy.createFrom can just be thought of as setting the object's
[[Handler]] to an actual ES object.  The abstract [[Handler]] could
either be implemented via pseudocode similar to the ES5 spec or by
actual ES code if a testable / executable object spec is desired.

I've been working on a concept called object descriptors which are
an object level equivalent of property descriptors.  One of the object
descriptor attributes I'm including is handler.  Object descriptors
could also have a configurable attribute which could control whether
an object's handler (and other attributes) can be changed.

On Fri, May 27, 2011 at 9:21 AM, Brendan Eich bren...@mozilla.com wrote:
 On May 27, 2011, at 3:04 AM, David Bruant wrote:

 The idea of permitting this becomes operation only for extensible objects
 with configurable properties is crucial.

 Is it? The first time I heard about the become operation was in the
 context of the proxy fix trap. Second time was this message. It doesn't
 sounds crucial yet to me.

 The crucial applied to both only for extensible objects with configurable
 properties in that sentence. ;-)
 The issue as I understand it is not becomes per se (more below), rather that
 an extensible object with configurable (own) properties could have those
 properties wrapped by accessors to emulate some of the intercessive power of
 proxies. From the security point of view, you want frozen and sealed
 objects, at least, to be immune to proxification because they are immune to
 such property-by-property wrapping with accessors, today.
 See Mark's reply on the list dated 7:33pm yesterday.

 The motivation is to unify ideas in proxies (in Harmony) with those proposed
 in http://wiki.ecmascript.org/doku.php?id=strawman:observe.

 I hadn't read this proposal yet. Thanks.

 I think that this discussion raises the following question:
 Should all usages of the become operation be associated with proxies?

 We are not exposing becomes in the language -- certainly not for two
 arbitrary live objects.
 In both the proxy fix case, and in this Proxy.createFrom case, one of the
 two objects is a newborn, not yet accessible. We brain-transplant between
 the accessible and inaccessible, swapping the objects' data. The identity is
 preserved but the internal and own properties are exchanged.
 Questions about the proxify-existing-object case:
 1. Won't the proxy want the original brain, the one transplanted into a
 newborn proxy (now become the regular object)?
 2. Will the costs here be acceptable compared to something unstratified
 requiring no extra object, a la strawman:observe?
 /be
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss





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


Re: Converting an existing object to a proxy

2011-05-27 Thread Sean Eagan
On Fri, May 27, 2011 at 10:10 AM, Sean Eagan seaneag...@gmail.com wrote:
 I think the separation between proxies and regular objects is too
 much.  I would prefer to think of proxies as just a special kind of
 object.  All objects could be thought of as having a handler (
 [[Handler]] ), and proxy objects could be those objects whose
 handler is an actual ES object as opposed to an abstract language
 specification object.

We could instead say that all objects have a [[DefaultHandler]] which
contains the default trap implementations.  Then object's that have a
[[Handler]] are proxy objects.  For trap resolution if an object has
a [[Handler]] and the [[Handler]] has the given trap, invoke it.  If
an object does not have a [[Handler]] or [[Handler]] does not have the
given trap, then, for derived traps invoke the object's
[[DefaultHandler]]'s trap, for fundamental traps perform the abstract
spec defined pseudocode for the given internal method.  Then proxy
fixing would mean that the object will no longer have a [[Handler]],
and Proxy.createFrom means that the object will now have a
[[Handler]].

We could also define default handler's for object types which override
certain internal methods such as Arrays and Functions.  These would
inherit the trap implementations from Object's default handler.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Converting an existing object to a proxy

2011-05-27 Thread Brendan Eich
On May 27, 2011, at 8:10 AM, Sean Eagan wrote:

 I think the separation between proxies and regular objects is too
 much.  I would prefer to think of proxies as just a special kind of
 object.  All objects could be thought of as having a handler (
 [[Handler]] ), and proxy objects could be those objects whose
 handler is an actual ES object as opposed to an abstract language
 specification object.

This is a way of thinking about proxies in the context of JS, for sure. Please 
see this slide

http://brendaneich.com/brendaneich_content/uploads/selective-interception.png

from Tom and Mark.


  This would be similar to the distinction
 betweeen data and accessor properties, since you could think of a
 default abstract [[Set]] and [[Get]] implementation for property
 descriptors.  Then fixing a proxy object could just be thought of as
 setting the object's [[Handler]] to an abstract specification handler,
 and Proxy.createFrom can just be thought of as setting the object's
 [[Handler]] to an actual ES object.  The abstract [[Handler]] could
 either be implemented via pseudocode similar to the ES5 spec or by
 actual ES code if a testable / executable object spec is desired.

The problem is making the VM handlers (to use the slide's terms) concrete, 
not abstract. No VM implementor wants that. Nor do security folks -- at least 
not read/write VM handler access.

When we first started discussing catch-alls, before Proxies were proposed, 
TC39 members stopped progress on catch-alls by citing the climbing the meta 
ladder problem. This is where the spec and real code, instead of bottoming out 
at unspoofable core semantics, trap back into user code doing 
meta-programming of arbitrary objects.

This is why VM implementors object. They can't optimize as well if they have to 
check more potentially varying invariants of ES1-5. This is why Proxies are a 
special kind of object.

The security issue is similar. If an attacker can vary invariants the VM needs 
to enforce via a built-in handler to preserve integrity or other safety 
properties, that's a security hole. It may be that frozen and sealed objects 
being immune is enough, for some operations such as watching gets and sets. As 
noted, for a non-sealed object, those could be done by wrapping each property 
in an accessor after transplanting it to an inner object or a peer property 
with a private name. But intercession at the VM handler layer may be strictly 
more powerful than get, set, or even delete trapping.


 I've been working on a concept called object descriptors which are
 an object level equivalent of property descriptors.  One of the object
 descriptor attributes I'm including is handler.  Object descriptors
 could also have a configurable attribute which could control whether
 an object's handler (and other attributes) can be changed.

This helps but the VM implementors may still object to reflecting 
currently-hidden VM handlers. There may be security issues we are missing. And 
unless the built-in objects of Clause 15 all have non-configurable handlers, 
you are talking about climbing the meta ladder in the spec.

/be

 
 On Fri, May 27, 2011 at 9:21 AM, Brendan Eich bren...@mozilla.com wrote:
 On May 27, 2011, at 3:04 AM, David Bruant wrote:
 
 The idea of permitting this becomes operation only for extensible objects
 with configurable properties is crucial.
 
 Is it? The first time I heard about the become operation was in the
 context of the proxy fix trap. Second time was this message. It doesn't
 sounds crucial yet to me.
 
 The crucial applied to both only for extensible objects with configurable
 properties in that sentence. ;-)
 The issue as I understand it is not becomes per se (more below), rather that
 an extensible object with configurable (own) properties could have those
 properties wrapped by accessors to emulate some of the intercessive power of
 proxies. From the security point of view, you want frozen and sealed
 objects, at least, to be immune to proxification because they are immune to
 such property-by-property wrapping with accessors, today.
 See Mark's reply on the list dated 7:33pm yesterday.
 
 The motivation is to unify ideas in proxies (in Harmony) with those proposed
 in http://wiki.ecmascript.org/doku.php?id=strawman:observe.
 
 I hadn't read this proposal yet. Thanks.
 
 I think that this discussion raises the following question:
 Should all usages of the become operation be associated with proxies?
 
 We are not exposing becomes in the language -- certainly not for two
 arbitrary live objects.
 In both the proxy fix case, and in this Proxy.createFrom case, one of the
 two objects is a newborn, not yet accessible. We brain-transplant between
 the accessible and inaccessible, swapping the objects' data. The identity is
 preserved but the internal and own properties are exchanged.
 Questions about the proxify-existing-object case:
 1. Won't the proxy want the original brain, the one transplanted into a
 newborn proxy 

Re: Converting an existing object to a proxy

2011-05-27 Thread Sean Eagan
Thanks, I wasn't aware of that history.

I'm not suggesting that default handlers or traps even should exist
from an implementation perspective, just that they could be a nice
specification mechanism now that we have proxies.  Otherwise we need
to separately maintain pseudocode and ES versions of the derived
traps.  The default handlers would specify the required *effective*
behavior of internal methods corresponding to derived traps.  Each of
the internal spec methods would still be abstract, and allowed to
perform additional behavior, but internal methods corresponding to
derived traps would need to also perform the behavior specified by the
default trap when the object does not have a [[Handler]] with that
trap.  It would need to behave as if the original bindings of the
builtin objects referenced within the default trap implementation were
used, except that even if the implementation allows property access
watching, no such notifications would be sent for property access on
builtins that occur within the default trap's code.

On Fri, May 27, 2011 at 11:12 AM, Brendan Eich bren...@mozilla.com wrote:
 On May 27, 2011, at 8:10 AM, Sean Eagan wrote:

 I think the separation between proxies and regular objects is too
 much.  I would prefer to think of proxies as just a special kind of
 object.  All objects could be thought of as having a handler (
 [[Handler]] ), and proxy objects could be those objects whose
 handler is an actual ES object as opposed to an abstract language
 specification object.

 This is a way of thinking about proxies in the context of JS, for sure. 
 Please see this slide

 http://brendaneich.com/brendaneich_content/uploads/selective-interception.png

 from Tom and Mark.


  This would be similar to the distinction
 betweeen data and accessor properties, since you could think of a
 default abstract [[Set]] and [[Get]] implementation for property
 descriptors.  Then fixing a proxy object could just be thought of as
 setting the object's [[Handler]] to an abstract specification handler,
 and Proxy.createFrom can just be thought of as setting the object's
 [[Handler]] to an actual ES object.  The abstract [[Handler]] could
 either be implemented via pseudocode similar to the ES5 spec or by
 actual ES code if a testable / executable object spec is desired.

 The problem is making the VM handlers (to use the slide's terms) concrete, 
 not abstract. No VM implementor wants that. Nor do security folks -- at least 
 not read/write VM handler access.

 When we first started discussing catch-alls, before Proxies were proposed, 
 TC39 members stopped progress on catch-alls by citing the climbing the meta 
 ladder problem. This is where the spec and real code, instead of bottoming 
 out at unspoofable core semantics, trap back into user code doing 
 meta-programming of arbitrary objects.

 This is why VM implementors object. They can't optimize as well if they have 
 to check more potentially varying invariants of ES1-5. This is why Proxies 
 are a special kind of object.

 The security issue is similar. If an attacker can vary invariants the VM 
 needs to enforce via a built-in handler to preserve integrity or other safety 
 properties, that's a security hole. It may be that frozen and sealed objects 
 being immune is enough, for some operations such as watching gets and sets. 
 As noted, for a non-sealed object, those could be done by wrapping each 
 property in an accessor after transplanting it to an inner object or a peer 
 property with a private name. But intercession at the VM handler layer may be 
 strictly more powerful than get, set, or even delete trapping.


 I've been working on a concept called object descriptors which are
 an object level equivalent of property descriptors.  One of the object
 descriptor attributes I'm including is handler.  Object descriptors
 could also have a configurable attribute which could control whether
 an object's handler (and other attributes) can be changed.

 This helps but the VM implementors may still object to reflecting 
 currently-hidden VM handlers. There may be security issues we are missing. 
 And unless the built-in objects of Clause 15 all have non-configurable 
 handlers, you are talking about climbing the meta ladder in the spec.

 /be


 On Fri, May 27, 2011 at 9:21 AM, Brendan Eich bren...@mozilla.com wrote:
 On May 27, 2011, at 3:04 AM, David Bruant wrote:

 The idea of permitting this becomes operation only for extensible objects
 with configurable properties is crucial.

 Is it? The first time I heard about the become operation was in the
 context of the proxy fix trap. Second time was this message. It doesn't
 sounds crucial yet to me.

 The crucial applied to both only for extensible objects with configurable
 properties in that sentence. ;-)
 The issue as I understand it is not becomes per se (more below), rather that
 an extensible object with configurable (own) properties could have those
 properties wrapped by accessors to 

Re: Converting an existing object to a proxy

2011-05-27 Thread Sean Eagan
On Fri, May 27, 2011 at 12:18 PM, Sean Eagan seaneag...@gmail.com wrote:
 Thanks, I wasn't aware of that history.

 I'm not suggesting that default handlers or traps even should exist
 from an implementation perspective, just that they could be a nice
 specification mechanism now that we have proxies.  Otherwise we need
 to separately maintain pseudocode and ES versions of the derived
 traps.

Of course you could go the other way, and remove the default trap
implementations.  All objects could have the same internal method
implementation regardless of whether or not they are a proxy.  Within
each internal method there could be a check as to whether the object
is a proxy (has a [[Handler]]) AND has the trap, if so, it is invoked,
otherwise the default pseudocode is performed.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Converting an existing object to a proxy

2011-05-27 Thread Andreas Rossberg
I'm puzzled about this idea. I thought that one of the main design
goals of proxies was that they are transparent, i.e. you cannot tell a
proxy apart from a proper object. How can this be maintained for
Proxy.createFrom? AFAICS, there is no way you can perform this
operation on an object that already is a proxy.

/Andreas


On 27 May 2011 04:13, Mark S. Miller erig...@google.com wrote:
 On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan cor...@cs.ucsc.edu wrote:

 [documenting/expanding some ideas briefly discussed at today's meeting]

 The current proxy proposal has a method to create a new proxy:

 var proxy = Proxy.create(handler, proto);

 We could extend this proposal to allow an existing object to be
 converted to a proxy, via:

 var proxy = Proxy.createFrom(object, handler, proto);

 Here, the return value 'proxy' is the same address as the argument
 'object'.
 The original object thus becomes a proxy. Any state of the original object
 is discarded.

 This extension appears to support additional applications, such as
 registering an observer on an existing object. The target object would
 first be cloned, then the target object would be converted into a proxy
 that
 dispatches to the cloned object, but which also notifies observers about
 accesses/updates to the (now proxified) object.

 There are a number of open issues relating to security etc:
 In particular, what objects can be proxified in this way - perhaps not
 frozen object,
 or objects with non-configurable properties or with unique names.

 In today's meeting, I made two suggestions along these lines:
 * Given the current proxy semantics, we should allow this only if the
 object-to-be-proxified is extensible and has no non-configurable own
 properties.
 * We have on occasion discussed modifying the proxy proposal so that
 individual properties could be fixed rather than just the proxy as a whole.
 (Note: I am not in favor of such a change, but it could be done soundly.)
 Given that this change to proxies were done, then we should allow
 proxification only if the object-to-be-proxified is extensible, period.
 In both cases, as you state, one effect of the operation is to remove all
 configurable own properties from the object. In both cases, we can adopt the
 rationale that the object-to-be-proxified could not have taken any action
 inconsistent with it always having been a proxy.
 In both cases, we need the further restriction that it is a kind of object
 that can be emulated by a proxy. Today, this is technically only objects of
 [[Class]] Object or Function, but we're talking about relaxing that in
 any case.


 A design goal is that for any object that could be proxified,
 we can replace it with a proxy in a way that is semantically transparent.

       - Cormac



 --
     Cheers,
     --MarkM

 ___
 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: Converting an existing object to a proxy

2011-05-27 Thread Cormac Flanagan
On Fri, May 27, 2011 at 2:26 AM, David Bruant david.bru...@labri.fr wrote:
 On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan cor...@cs.ucsc.edu wrote:
 A design goal is that for any object that could be proxified,
 we can replace it with a proxy in a way that is semantically transparent.

 If you provide the ability to put any functions in the handler object, there
 in no such thing as semantically transparent. The handler methods can do
 whatever they wants; they are functions.

What I meant was that by writing the handler functions in the appropriate way,
we can create a proxy that is semantically transparent -- not that all proxies
must be semantically transparent.

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


Re: Converting an existing object to a proxy

2011-05-27 Thread Sean Eagan
On Fri, May 27, 2011 at 12:43 PM, Sean Eagan seaneag...@gmail.com wrote:
 Of course you could go the other way, and remove the default trap
 implementations.  All objects could have the same internal method
 implementation regardless of whether or not they are a proxy.  Within
 each internal method there could be a check as to whether the object
 is a proxy (has a [[Handler]]) AND has the trap, if so, it is invoked,
 otherwise the default pseudocode is performed.

The pseudocode for checking if the object has a [[Handler]], and if
that [[Handler]] has a trap, and then invoking the trap could all be
factored out into a [[Trap]] (or something) internal method, which
takes a trap name, and a list of arguments to pass to the trap, and
returns whether or not the object has the trap, and if so, also a
return value from the trap.  This would make for a very concise and
clear spec with regard to proxies, and it would be relatively easy to
update the current proposal to do this.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Converting an existing object to a proxy

2011-05-27 Thread Sean Eagan
On Fri, May 27, 2011 at 1:05 PM, Sean Eagan seaneag...@gmail.com wrote:
 On Fri, May 27, 2011 at 12:43 PM, Sean Eagan seaneag...@gmail.com wrote:
 Of course you could go the other way, and remove the default trap
 implementations.  All objects could have the same internal method
 implementation regardless of whether or not they are a proxy.  Within
 each internal method there could be a check as to whether the object
 is a proxy (has a [[Handler]]) AND has the trap, if so, it is invoked,
 otherwise the default pseudocode is performed.

 The pseudocode for checking if the object has a [[Handler]], and if
 that [[Handler]] has a trap, and then invoking the trap could all be
 factored out into a [[Trap]] (or something) internal method, which
 takes a trap name, and a list of arguments to pass to the trap, and
 returns whether or not the object has the trap, and if so, also a
 return value from the trap.  This would make for a very concise and
 clear spec with regard to proxies, and it would be relatively easy to
 update the current proposal to do this.


For expository purposes it might still be useful to have actual ES
versions of the default pseudocode sections of the internal methods
somewhere.  This could either be via a non-normative addendum to the
spec, or left up to the community to provide outside the spec.  The
latter option might be better since it could be updated independent of
the spec in case of any bugs found.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Converting an existing object to a proxy

2011-05-27 Thread Sean Eagan
On Fri, May 27, 2011 at 1:05 PM, Sean Eagan seaneag...@gmail.com wrote:
 On Fri, May 27, 2011 at 12:43 PM, Sean Eagan seaneag...@gmail.com wrote:
 Of course you could go the other way, and remove the default trap
 implementations.  All objects could have the same internal method
 implementation regardless of whether or not they are a proxy.  Within
 each internal method there could be a check as to whether the object
 is a proxy (has a [[Handler]]) AND has the trap, if so, it is invoked,
 otherwise the default pseudocode is performed.

 The pseudocode for checking if the object has a [[Handler]], and if
 that [[Handler]] has a trap, and then invoking the trap could all be
 factored out into a [[Trap]] (or something) internal method, which
 takes a trap name, and a list of arguments to pass to the trap, and
 returns whether or not the object has the trap, and if so, also a
 return value from the trap.  This would make for a very concise and
 clear spec with regard to proxies, and it would be relatively easy to
 update the current proposal to do this.

[[Trap]] would also need to take a boolean throw argument as to
whether it should throw if the object has the handler, but does not
have the trap.  This argument would be set to true for fundamental
traps, and false for derived traps.  It would not need to take an
argument corresponding to the trap proxy argument since that could
be appended within [[Trap]] itself.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Converting an existing object to a proxy

2011-05-26 Thread Cormac Flanagan
[documenting/expanding some ideas briefly discussed at today's meeting]

The current proxy proposal has a method to create a new proxy:

var proxy = Proxy.create(handler, proto);

We could extend this proposal to allow an existing object to be
converted to a proxy, via:

var proxy = Proxy.createFrom(object, handler, proto);

Here, the return value 'proxy' is the same address as the argument 'object'.
The original object thus becomes a proxy. Any state of the original object
is discarded.

This extension appears to support additional applications, such as
registering an observer on an existing object. The target object would
first be cloned, then the target object would be converted into a proxy that
dispatches to the cloned object, but which also notifies observers about
accesses/updates to the (now proxified) object.

There are a number of open issues relating to security etc:
In particular, what objects can be proxified in this way - perhaps not
frozen object,
or objects with non-configurable properties or with unique names.

A design goal is that for any object that could be proxified,
we can replace it with a proxy in a way that is semantically transparent.

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