On 18 October 2011 17:48, Tom Van Cutsem <tomvc...@gmail.com> wrote: > 2011/10/18 Andreas Rossberg <rossb...@google.com> >> >> First, Proxy.startTrapping (a.k.a. Proxy.attach). As far as I can see, >> this implies a significantly more general 'become' operation than the >> current semantics. I don't see how we can implement that without >> substantial (and potentially costly) changes to VMs, like support for >> transparent forwarding references. I also share Dave's concerns >> regarding conflation of "non-attachability" and "non-extensibility". > > Your concerns are justified and this is why we need implementors to study > the strawman. I'm not an implementor, so I have no clue as to the actual > implementation costs of supporting Proxy.startTrapping. Yes, it is a very > powerful operation. Not as powerful as Smalltalk's "become", but getting > close. Since the target would become a "fresh" proxy object, perhaps tricks > similar to those used to make the old "fix()" behavior work could be used > (swapping the internals of two objects). I realize this is highly > VM-specific.
The trick that you can use with the current proposal won't work any longer. In the current semantics, the only two possible 'become' transitions are proxy->JSobject and functionproxy->JSfunction. It is easy to implement 'become' by just overwriting the object itself. All you need to ensure is that the representation of a proxy is large enough for the representation of a regular object (and similarly for functions). Proxy.startTrapping, however, goes the other way, with more general transitions. To use the same trick one would need to make any object to which a proxy can be attached at least as large as a proxy (or the other way round, be able to represent proxies in a way that takes at most as much space as the smallest object you can attach to). With some extra work and indirection overhead, we could implement a proxy object in two words. But that might not be good enough, e.g. when attaching to foreign ("host") objects or some internal ones. >> Proxy.stopTrapping worries me, too, especially in combination with >> attaching. It seems like I could create a proxy p, then later want to >> deactivate trapping for my handler. But in the meantime, somebody else >> morphed my p into his own proxy by invoking startTrapping(p). So >> stopTrapping(p) would deactivate his handler, not mine. So, the >> proposed interface seems broken to me. > > Good point. Yet another reason why I prefer the alternate Proxy.temporaryFor > API I sketched in reply to Dave Herman. That API does not necessarily suffer > from this issue. Yes, I think that interface, while less slick, is the right one. >> Finally, I'm not sure I fully understand the performance implications >> of direct proxies vs the current proposal. From looking at your >> prototype implementation, it seems that we need quite a number of >> additional checks and calls, even for non-fixed properties. Can you >> perhaps quantify that overhead a bit? > > Taken together, lots of checks are needed, but the amount of checks per trap > is fairly limited. Also, most checks reuse the pathways of existing > primitives like delete and defineProperty. In the scenario where we are > wrapping a target object, we're trading one type of overhead for another: in > the current proxy proposal, say I only want to intercept "gets" on a target > object. I am still forced to implement a full ForwardingHandler (in JS > itself), and override only its 'get' trap. All operations other than "get" > incur an unnecessary overhead: the operation must trap the handler, only to > have the handler forward the operation anyway (IOW: the operation is lifted > to the meta-level, only to be lowered to base-level immediately afterward). > With direct proxies, all traps other than "get" should incur very little > overhead. I envision that a direct proxy can very efficiently forward an > operation to the target, no need to lift & lower. On the other hand, now the > "get" operation will incur an additional check to verify that its reported > result is consistent with the target object (only if the property was > previously exposed as non-configurable). > I'm speculating at this stage, but I assume that the vast majority of > existing JS code does not use Object.getOwnPropertyDescriptor, hence has no > way of determining whether a property is non-configurable, hence does not > activate the more expensive checks. The overhead then is mostly checking > whether the corresponding target object's property is non-configurable. > In any case, I'm not sure that performing micro-benchmarks on my > DirectProxies.js prototype implementation will generate useful results: I > think it's too dependent on the current proxy implementation, and moreover > I'm sure that many of my checks can be done _way_ more efficiently at the > VM-level. For instance, to test whether a target property is > non-configurable, I check Object.getOwnPropertyDescriptor(target, > name).configurable. In a VM I presume this can be made considerably more > efficient. No need to allocate a property descriptor just to test > configurability, for a start. Thanks for the summary, that is helpful. I agree that lots of these checks will be far more efficient when implemented in a VM. [Sorry, have to run now.] Thanks, /Andreas _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss