Mark, below what you refer to as [[SetProtoype]] is essentially the 
[[SetInhertiance]] MOP operations in the current spec. draft there is also a 
[[GetInheritance]].  It is called Get/SetInheritance because it doesn't 
necessarily manipulate the [[Prototype]] of the object it is invoked upon (eg, 
if it is a Proxy) and for exotic objects property inheritance isn't constrained 
to use [[Prototype]].

On Apr 23, 2013, at 5:11 AM, Mark S. Miller wrote:

> Ok, I have read more messages on this thread and looked at some of the 
> supporting material that has been pointed at. The notes from the last meeting 
> record a conversation before I arrived, and I'm not quite clear what it says 
> was agreed on. In any case, I think the primary goals should be and seem to 
> have been
> 
> * minimize magic
> * maximize security
> * codify something everyone can agree to implement
> 
> The first two goals generally align well anyway. I think this is best served 
> by something that seems at least close to what was agreed on:
> 
> 
> * The syntax that we've already agreed to on this thread: {__proto__: ....} 
> is special syntax that initialized the [[Prototype]]. No need for anything 
> even as mildly imperative as [[SetPrototype]]. 

The semantics of the syntax still should be specified in terms of the MOP as 
it's in the ordinary object MOP internal methods that we specify their 
semantics 

> 
> * { [ "__proto__" ]: .... } is not special in any way, and creates a normal 
> property named "__proto__".

I don't believe this is legal. Didn't we agree w to support [ ] property keys 
that evaluate to symbols.

> 
> * Every object with a potentially mutable [[Prototype]] must be identified 
> with a realm of origin. (Practically this will be "any object", which is good 
> because that is what Weak References will need anyway.)

> 
> * In the initial state of a normal realm, Object.prototype.__proto__ is an 
> accessor property with the descriptor (making up names for the internal 
> functions -- don't take the names seriously):
> 
> { getter: [[ProtoGetter]], setter: [[ProtoSetter]], enumerable: false, 
> configurable: true }
> 
> * In this initial state, Object.getOwnPropertyDescriptor(Object.prototype, 
> '__proto__') returns the above descriptor. No magic.
> 
> * In this initial state, Object.getOwnPropertyNames(Object.prototype) returns 
> a list which includes the string "__proto__". No magic.
> 
> * Likewise for all other reflective operations, including "in". No magic.

So, getOwnPropertyKeys(Object.prototype) is expected to yield "__proto__"
> 
> 
> * The behavior of [[ProtoGetter]] is approximately 
> 
>     function [[ProtoGetter]] () { return Object.getPrototypeOf(this); }
  
it would actually be specified in terns of [[GetInheritance]] MOP operations

> 
> except of course that it uses the internal function rather than the current 
> binding of Object.getPrototypeOf. Just like Object.getPrototypeOf, this 
> behavior is independent of Realm. It is also independent of whether 
> [[ProtoGetter]] is invoked *as* an accessor or invoked otherwise, for example 
> by using Function.prototype.call.
> 
> 
> * The behavior of [[ProtoSetter]] is approximately
> 
>     function [[ProtoSetter]] (newValue) {
>         if ([[GetRealm]](this) !== [[GetRealm]]([[ProtoSetter]])) {
>             throw new TypeError(....); // or should this be RangeError ?
>         }
>         this.[[SetPrototype]](newValue);
>     }

In the past there were other restrictions that have been suggested.  For 
example, not allowing:
   Object.prototype.__proto__ = notNull;
to do what the above a=names suggest.

Regardless, what is so special about the [[ProtoSetter]] operation that it 
needs to be restricted in this way?  It's just a capability and you know how to 
control access to capabilities.  You also know how to protect objects from 
having their [[Prototype]] mutated.  If I have any object, that inherits from a 
different realm's Object.prototype I can navigate to its constructor property 
which gives me access to that other realm's, Object.create, Object[[@@create], 
and all the other Object.* functions.  Why isn't being able to find and  apply 
some other realms Object.free just as scary as finding its [[ProtoSetter]]?

Allen





> 
> This behavior is independent of whether [[ProtoSetter]] is invoked *as* an 
> accessor or invoked otherwise, for example by using Function.prototype.call.
> 
> 
> * Normal objects have a [[SetPrototype]] method like
> 
>     function [[SetPrototype]] (newValue) {
>         // normal checks for proto acceptability
>         // * either null or an object
>         // * would not create an inheritance cycle
>         this.[[Prototype]] = newValue;
>     }
> 
> 
> 
> 
> ======== Warning: The rest of this is half baked ============
> 
> * Direct proxies have a [[SetPrototype]] method that invokes the handler's 
> "setPrototype" trap. It is the *handler's* responsibility, not the proxy's, 
> to set the target's [[Prototype]] to newValue. Once the handler returns to 
> the proxy, the proxy checks if target.[[Prototype]] === newValue. If not, it 
> throws. This enforces that a handler can only reflect the mutation of 
> [[Prototype]] transparently if it already has setter which is the capability 
> to do so.
> 

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to