Le 31/10/2012 19:03, Allen Wirfs-Brock a écrit : > Let me summarize what I think is your concern. > > In ES5, property descriptor records are a specification device that is used > to transport information about object properties between factored components > of the ES specification. The same information can be expressed as an ES > object that is produced/consumed by Object.getOwnPropertyDescriptor and > Object.defineProperty. These are raising/lowering operations that move > information from the specification/implication level to the reflective ES > language level. One advantage of this layering is that the conversion > to/from an actual object takes place once, at a well defined point in the > execution sequence and any side-effects of object access occur only at that > point. Once the information is represented as an internal "record" we know > that all internal consistency preconditions are satisfied and that no > side-effects can be associated with access to such records. The part about precondition is particularly interesting and I agree it should be kept. However, it's possible to define ECMAScript contructs that enforce such pre-conditions. My point is that even for the spec, it's possible to define PropertyDescriptors by using ECMAScript constructs, without necessarily creating a new spec-only type.
> You concern seems to be that a proxy traps that deal with descriptor objects > have no such guarantees and in particular strange things might happen if a > descriptor object is itself a proxy. My original concern was that the defineProperty and getOwnPropertyDescriptor traps I/O were interacting directly with PropertyDescriptor algorithms, but after re-reading the proxy spec page more carefully, I realized it is not the case. However, not being the case has a cost: The proxies_spec page [1] redefines some ES5 15.2.3.* built-ins. Core of the current Object.getOwnPropertyDescriptor is : 3) Let desc be the result of calling the [[GetOwnProperty]] internal method of O with argument name. 4) Return the result of calling FromPropertyDescriptor(desc) (8.10.4). Core of the proposed Object.getOwnPropertyDescriptor is : 3) If O is a proxy Return the result of calling TrapGetOwnProperty(O, name) 4) Let desc be the result of calling the [[GetOwnProperty]] internal method of O with argument name. 5) Return the result of calling FromPropertyDescriptor(desc) (8.10.4). If [[GetOwnProperty]] returned the same type of thing than TrapGetOwnProperty (which returns an object), the spec 15.2.3.3 Object.getOwnPropertyDescriptor could remain the same. Also, I have the feeling that there is duplicated logic between TrapGetOwnProperty and FromPropertyDescriptor or unnecessary back and forth conversions between internal PropertyDescriptor and objects. Currently, TrapGetOwnProperty returns an object, but when there is an actual trap, it goes through: * NormalizeAndCompletePropertyDescriptor(Object) -> Object (step 6) * ToCompletePropertyDescriptor(Object) -> PropertyDescriptor (step 3 of NormalizeAndCompletePropertyDescriptor) * FromPropertyDescriptor(PropertyDescriptor) -> Object (step 4 of NormalizeAndCompletePropertyDescriptor) We might as well get rid of the spec-only PropertyDescriptor, define an equivalently pre-condition/invariant enforcing ES5 construct and manipulate that both internally and in trap boundaries. > The getOwnPropertyDescriptor trap is a lowering operation. (...) > > The defineProperty trap is a raising operation. (...) > > The other possible concern would be that a trap might directly use > Object.getOwnPropertyDescriptor on a proxy object and that this might provide > a bogus descriptor. But it can't. (...) I agree with what you wrote here. Basically, the thing that prevent potentially harmful descriptors-as-proxies to being harmful is that from getOwnPropertyDescriptor and to defineProperty traps, the "essence" of the descriptor is copied to a fresh object created internally. > so, I just don't see any basis for your concern. Perhaps, you could > elaborate on the nature of the problem as you perceive it. Let's try to ASCII-art it. Here are the paths that property descriptors take. Arrows represent a internal type conversion and/or descriptor completion/normalization # Object.defineProperty on regular object: ES Object (in user script) --> PropertyDescriptor (and stored as such) # Object.defineProperty on proxies (as I understand its current specification): ES Object --> PropertyDescriptor --> ES Object (for trap argument) --> PropertyDescriptor The last arrow is not compulsory, but we can decently assume that for most cases, the defineProperty trap will forward the operation to the target # What I'm suggesting is to do the following in both cases: ES Object --> ESUsablePropDesc (used for proxy trap arguments) I think I was wrong in suggesting using raw ES6 Maps (and I think I understand that's what Andreas meant regarding heterogeneous types). The idea of ESUsablePropDesc is that it preserves pre-conditions and invariants of property descriptors very much like the internal type currently does. It can be used both internally in the spec as well as in proxy traps. When forwarding the ESUsablePropDesc object to the target, there is no need for conversion once again. The engine generated it and enforced/normalized anything it needed already. Potentially, when using ESUsablePropDesc descriptors directly (which could become an option), the engine may not need to convert them, because it already has enforced invariants/normalization, prevented inconsistent states, etc. The way I see it now, ESUsablePropDesc would be a regular object with a bunch of getter/setters to enforce property descriptor invariants. Everything would remain compatible (unless people really cared that ES5 descriptors have data properties). The proxy side of things would be more efficient, the door would be open to make non-proxy use of Object.defineProperty/getOwnPropertyDescriptor more efficient. David [1] http://wiki.ecmascript.org/doku.php?id=harmony:proxies_spec _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss