Le 24/11/2012 18:10, Allen Wirfs-Brock a écrit :
* [[Enumerate]], [[Keys]] and [[OwnPropertyKeys]] are very close operations * So are [[PreventExtensions]]/[[Freeze]]/[[Seal]] on one side and [[IsExtensible]]/[[IsFrozen]]/[[IsSealed]]

I'm afraid that making them distinct operations increases footgun-ness. [[HasProperty]] has been removed in favored of [[HasOwnProperty]] (which might be removed in favor of only keeping [[GetOwnProperty]], though the conclusion of the discussion was the keep both IIRC) because the former could be "robustly" composed between

Yes, I agree. In particular I think [[Enumerate]], [[Keys]], and [[OwnPropertyKeys]] should be reduced to a single parameterized trap. Multiple traps make it harder to create an internally consistent MOP provider (eg, Proxy handler).

(...)


Here is an idea to uniformize the enumeration story while removing enumeration inconsistency footgun. I'll describe it in proxy trap terms. A unique trap (or internal operation)
keyEnumerate: () -> iterator for {propertyKey, enumerable}
There is this unique operation which returns an iterator not for property keys, but for an object containing a property key and a boolean signifying the enumerable boolean. Using this, each userland operation would use this iterator, drain it out (unless the iteration is being aborted like by throwing in a for-in loop) and filter out based on the exact userland operation so that:
* All would filter out if propertyKey is ever a private symbol
* Object.getOwnPropertyNames would keep all other property keys regardless of the enumerable value * Object.keys would filter out properties which are described as non-enumerable * for-in would filter out non-enumerable and retrieve the different keyEnumerate from the prototype chain objects. With this unique internal operation, an object is able to communicate its intent regarding what's enumerated and each enumeration userland operation only keeps what it's interested in.

Yes, something like this. My inclination would be to add a hint parameter indicating one of the currently known variations. I think it is justified as enabling the "handler" to optimize its internal work of collecting the set of keys.
I'm afraid an hint parameter has the same downside than having several traps: offering the possibility to make different code paths for different userland enumeration operations. This very possibility is the footgun in my opinion. I felt satisfied with the [[keyEnumerate]] internal operation, because as a trap, people will have to return an iterator that iterates over everything and the engine (not the trap) makes the call of what is to be actually enumerated by the different variations. Not letting the trap know how the result will be used is the best way to prevent people from writing erroneous traps in my opinion.



• Defined all of the functions in the @Reflect module corresponding to MOP internal operations.
IIRC __proto__ has been agreed to be an data property and there was no Reflect.setPrototypeOf operation in the harmony Reflect module proposal on purpose so that 'delete Object.prototype.__proto__' at any point would be enough to be sure that all [[Prototype]]-setting capabilities are removed.
So I think the Reflect.setPrototypeOf  should be removed.

Do you want to be able to set __proto__ on DOM objects and other exotic objects?
I personally don't, but for sure others do. I'm happy with the static inheritance mechanism we will soon have and cover the vast majority of current __proto__ use cases. Adding Reflect.setPrototypeOf has exactly the same issues than an extractable __proto__ setter. See May meeting notes [1]: "DH: I can predict the security bugs: the implementor just thinks about the normal case, but the attacker takes the accessor out, installs it on an object that inherits from a proxy to an object from another global etc. etc. and something internal breaks MM: that's the most compelling argument I've heard. the additional testing surface area is much bigger"

__proto__ really is in ES6 as a de facto standard. I'm not sure it is a good enough reason to make setting the [[Prototype]] a first citizen of the language.


If so, it needs to be part of the MOP. "In for a penny, in for a pound". If we are going to make __proto__ part of the language than we have to accommodate just like any other feature. If you want to be able to disable it make deletion of Reflect.setPrototypeOf be the switch. Or define a new function for doing it. But I don't think we should be bending the MOP to accommodate idioms like deleting __proto__.. Remember, the first point above. [[SetInheritance]] is a generic operation, only some objects implement via a [[Prototype]] internal data property.
In practice, it's all of them except in platforms with no __proto__, no? Even proxies have no way to override [[SetInheritance]]. Actually, if Reflect.setPrototypeOf is added, a setPrototypeOf handler trap needs to be added as well. Some previous discussions about __proto__ and proxies occurred at the July meeting [2].

David

[1] https://mail.mozilla.org/pipermail/es-discuss/2012-May/022834.html
[2] http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#discussed_during_tc39_july_2012_meeting_microsoft_redmond
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to