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