Le 01/09/2011 17:40, Tom Van Cutsem a écrit : > (...) > > A first strawman (the "short-circuiting approach" on the wiki page) > was based on having a proxy "cache" non-configurable properties, such > that if the proxy hit the cache, it would no longer trap the handler. > That design proved to be flawed, for several reasons, as pointed out > by David Bruant, IIRC. If i remember well, the main argument was that in the case of a forwarding proxy, if non-configurable properties related trap call go in the cache without actually calling the trap, then the forwarding proxy cannot forward the operation to the target (and then fails at its "forwarding" mission).
> (...) > > The full implementation of such "non-extensible proxies" is here: > <http://code.google.com/p/es-lab/source/browse/trunk/src/proxies/FixedTrappingProxy.js> Thanks :-) > The file's comments near the top contain a detailed description of the > invariants enforced by this type of proxy. Invariants on own properties trap (getOwnPropertyDescriptor, defineProperty, delete, hasOwn) are a somewhat direct interpretation of the invariants on the ES5.1 spec. However, invariants imposed on potentially inherited properties may be a bit more controversial. For instance, for the get trap, the fact that the value is unchanged is enforced (L.641, !Object.is). This is a "natural" extension of the ES5.1 invariant "If a property is described as a data property and its [[Writable]] and [[Configurable]] are both false, then the SameValue (according to 9.12) must be returned for the [[Value]] attribute of the property on all calls to [[GetOwnProperty]].", however, nothing in the spec enforces that the [[Get]] (get trap) should use [[GetOwnProperty]] and then be affected by the invariant. It is just how it happened to be spec'ed in 8.12.3 and host objects could decide to do otherwise. I'm not really sure what is the best to do. Either specify these invariants in the spec or remove the checks from the implementation. // - properties returned by the fix() trap are merged with fixed properties, // ensuring no incompatible changes can be made when calling freeze, seal, // preventExtensions // will throw if any of the props returned already exist in // fixedProps and are incompatible with existing attributes Object.defineProperties(this.fixedProps, props); I agree with this behavior. However it has some consequences. In order to avoid throws, the proxy author has to remember which properties are non-configurable (to avoid collisions when returning props) and the values of these (to avoid throwing) which is a duplication of what the engine has to remember to enforce the invariant. In order to avoid the duplication, the engine could provide this information in some way (additional trap argument? :-s). Also, for traps to know whether a proxy has been fixed, the additional proxy argument will be a good news (Object.isExtensible(proxy) from within a trap). I also like the idea of passing the type of operation (freeze, preventExtensions, seal) as a string which can allow, for instance from the fix trap of a forwarding proxy to do Object[operation](target). > I (lightly) tested this implementation on FF6 (the implementation > depends on both proxies and WeakMaps). For those interested: > console-based test: > <http://code.google.com/p/es-lab/source/browse/trunk/src/proxies/testFixedTrappingProxy.js> > browser-based test: > <http://code.google.com/p/es-lab/source/browse/trunk/src/proxies/testFixedTrappingProxy.html> > > Given the intricacy of the invariant checks, this code can use more > eyeballs. There's also a number of unresolved TODO's that merit > discussion, and some hints on a redesign of the fix() protocol. In > particular, Mark and I have been discussing a protocol where a handler > can _either_ tell the proxy that it wants to continue trapping, even > after being fixed, or that it wants to "become" a regular object as > before, with no more overhead for invariant checks. I think this gives > handler writers the "best of both worlds" in terms of flexibility and > performance. I really would like to see a native implementation of non-extensible with non-configurable properties proxies, because i am still not sure that there is an overhead in some cases. For instance, ES5.1 8.12.9 [[DefineOwnProperty]] for regular objects (http://es5.github.com/#x8.12.1 ) has very similar checks than in your code. Regardless, it's a good thing to provide the choice. Regarding the open issue ("do we default to Object.create or do we want to allow for the possibility of Array.create etc.?"), I think that the choice should be given to create any sort of object (why not host objects such as NodeList?). One question would be: how could this (easily) be achieved? Cheers, David _______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

