B.3.1 The __proto__ pseudo property

Mark S. Miller erights at google.com
Sun Apr 21 18:24:01 PDT 2013

On Sun, Apr 21, 2013 at 6:11 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

> On Apr 21, 2013, at 1:37 PM, Brendan Eich wrote:
> > Allen Wirfs-Brock wrote:
> >> On Apr 21, 2013, at 12:31 PM, Brendan Eich wrote:
> >> >  You don't want that to affect object literals evaluated in the same
> realm after such a deletion. Why not?
> >>
> >> Why should it?
> >
> > ... because it did in ES5-conforming implementations that support
> __proto__ as a de-facto standard *and* allow delete
> Object.prototype.__proto__.
> Was that intentional WRT object literals or an un intended consequence of
> using [[Put]] in processing that property.  Prior, to the ES6 discussions
> over the last year was that even the case?  For each major implementation
> how long has deleting Object.prototype.__proto__ (if it was even possible
> has that behavior).
> The point is that I don't think there is any long standing behavior in
> this regard relating to object literals and deleting
> Object.prototype.__proto__ that the web is dependent upon.  We are free to
> specify a semantics that will make sense, now and for the long term.
> >
> >>   We already used the existence of {__proto__: whatever} got rid of<|
> as declarative syntax for defining an object literal with a [[Prototype]]
> other than object prototype.  Making {__proto__: whatever}  only work some
> of the times means it isn't a reliable declarative syntax.
> >
> > What?
> >
> > Mark insists on delete Object.prototype.__proto__ making the magic go
> away. (Summoning Mark.)
> The major is foo.__proto__ = bar changing foo's dynamically changing foo's
> [[Prototype]].  There is nothing magic about an object literal that uses
> some weird syntax to specify the [[Prototype]] that a newly allocated
> object will have.
> >
> > Triangle died for several reasons, and I'm surprised to hear it here.
> Grinding an axe?
> Not at all!  You frequently have said that standardizing __proto__ takes
> the wind out of other features that support various use cases of
> defining/manipulating an object's [[Prototype]].  One of those features is
> using an object literal as a way to declaratively describe an object that
> inherits from something other than Object.prototype (including null).
> So, if {__proto__: null} is a solution for that use case it should be
> specified with reasonable semantics and not be a conditional feature whose
> availability is tied to something else that many consider undesirable.
> There is no need for any magic here and no need to introduce additional
> imperative behavior by calling [[Set]].  It is just creating an object with
> a syntactically provided [[Prototype]] value.
> Specifying it as doing a [[Set]] just opens the door for people inserting
> their own accessor.
> In ES5 we explicitly change object literals to be immune from such
> tampering and with apparently no ill-effect.  I don't see why we would want
> to re-open such an avenue.

I am embarrassed that I hadn't noticed that earlier. Allen is right. Having
this literal syntax imply a [[Set]] re-introduces a security vulnerability
that ES5 had fixed. This is a big deal. The object-literal semantics that
it seems Allen and I agree on has no such vulnerability.

>  It certainly is necessary from a specification perspective and it isn't
> going to have a big implementation impact to do it right.
> >
> >>   Why would we want to do that?  There is arguably a good motivation
> wanting disable the ability to dynamically __proto__ modify arbitrary
> pare-existing objects. But what is the motifacation for doing that on newly
> created objects?
> >
> > I will tag Mark in here, but first make my own move:
> >
> > Answer: because the clear way to implement this in ES5-conforming
> implementations that support __proto__ is to call [[Put]] not
> [[DefineOwnProperty]] if the name of the property being initialized in the
> object literal is '__proto__', and that's what engines implement.
> I'd say that the clearest conforming way is to just create the new object
> with the [[Prototype]] value that was provided using the literal.  [[Put]]
> isn't needed.  [[SetInhertiance]] also isn't really need, but it is
> semantically much closer than dong an operation that invokes an arbitrary
> set accessor.
> >
> > That makes a new de-facto standard, which you should not be wasting
> energy trying to break!
> I don't think there currently is a de facto standard at these edges.  Our
> job is to sort it out and make the best possible language for the long run.
> >
> >>> SpiderMonkey at least goes out of its way to do [[Set]] (let's call
> it) not [[DefineOwnProperty]] for 'o = {__proto__: 42}', so why wouldn't
> [[Set]] create a fresh property, seeing nothing on Object.prototype named
> '__proto__' with a setter to run?
> >>
> >> Because the semantics that says you can't use [[DefineOwnProperty]] may
> say to go out of the way to do something else.
> >
> > Too late, ES5+reality happened. You are now proposing to break the web,
> at the limit. JS implementors will not go for that, so you are wasting your
> time.
> No both, FF and V8 apparently have been evolving in this area over the
> last year and IE hasn't even entered the field yet.  Show me any
> significant, browser interoperable code on the web that is observably
> dependent upon object literals doing an observable [[Put]].

I'll go further with the challenge by dropping the "on the web". Show any
significant legacy-browser interoperable code (IE aside since it hadn't
implemented __proto__ historically) which would not be compatible with the
literal semantics Allen proposes.

> >
> >>   It my strawman spec. it says use [[SetInhertiance]] rather than
> [[Put]].  Either is a special case semantics and [[SetInheritance]] is a
> much more direct expression of the likely user intent.
> >
> > Direct, schmirect.
> >
> > This is about compatibility and consistency, not what you can edit into
> a draft. Please reconsider. Must we put this on the next meeting's agenda?
> I have to respectfully disagree.  So me the code that would break and
> explain why what ever consistency you are imaging is worth making object
> literals that specify a [[Prototype]] a unreliable features.  How is that
> better for anyone?
> yes, I intended to put this on the agenda since I now have sold spec.
> language to review.
> Allen
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130421/f596daad/attachment-0001.html>

More information about the es-discuss mailing list