Re: "var" declarations shadowing properties from Window.prototype

On Aug 10, 2012, at 6:30 AM, Boris Zbarsky wrote:

> On 8/10/12 2:08 AM, Brendan Eich wrote:
>> The most recent ECMA-262 spec, the 5th edition, tried going the other
>> way, toward "own", but we at Mozilla for Firefox implemented ES5 and ran
>> into trouble (see bug above), so we filed an ES5 erratum that was fixed
>> for the ISO version of ES5, and reverted our implementation in
>> SpiderMonkey to the long-standing de-facto standard.
> 
> Ah, lovely.  I'd missed this last bit happening, and hence also missed that the current behavior was no longer correct.
> 

I'm going to take a try setting this story straight:

Neither ES5 or ES5.1 does a "own" check for either global var or function declarations. See 10.5 step 5.c/8.b each of which calls HasBinding 10.2.1.2.1 which does a [[HasProperty]] which, if necessary, looks up the [[Prototype]] chain.

The change made in ES5.1 (renumbered existing ES5 10.5 step 5.e as 5.f and inserted a new step 5.e + substeps related to dealing with function declarations that over-wrote accessor properties (both own or inherited) of the global object as well function declarations that tried to redefined non-configurable global object properties.  This change was motivated by https://bugzilla.mozilla.org/show_bug.cgi?id=577325 and the es-discuss thread referenced in that bug.

Note that the ES5.1 change only related to function declarations.  ES5.1 did not  make any changes to the specified semantics of global var declarations. 

Subsequent discussion  of Mozilla bug 577325 lead to https://bugs.ecmascript.org/show_bug.cgi?id=78 .  It proposes an errata  (subsequently approved by TC39)  to ES5.1's 10.5 that extends the function declaration fix to apply to var declarations. It also changed the check for a pre-existing global property to a "own" check.  This latter change is presumably what has been implemented in FF and is causing the indexedDB issue. 

These post ES5.1 errata was based upon these  desired semantics:

1) "variable" accesses that bind to inherited properties of the global object
should return the current value of the inherited property.  (note such "variable" accesses
may be to properties created by function declarations)

2) "variable" assignments  to inherited properties of the global object should
be equivalent to a [[Put]] to the global object.  Whether or not a own property
is created depends upon the [[Writable]] attribute of the inherited property
and the extensible internal property of the global object.

3) global function and var declarations always create own properties of the
global object.  If an inherited property of the same name already exists it is
over-ridden with an own property. 

4) The declaration instantiation rules relating to pre-existing bindings
only consider own properties of the global object.  Inherited properties of the
global object have no effect upon the processing of function and var
declarations.

Supporting requirements 3&4 are where the "own" property checks were introduced. 

However, I don't thing we can just drop them without some careful thought.  If we did that, we would reintroduce problems related to global declarations firing inherited setters and also interactions between inherited property attributes and global declarations.

It feel like we are still playing semantics ping-pong with compat. bug paddles. I'm not sure that there is an ideal solution.  Perhaps we need to consider var and function declarations separately.  Perhaps we need be have different redeclaration rules for own and for inherited global object properties.  In any chase I think we need to do a more care analysis then just fixing this bug and it needs be be coordinated between the ES spec. and WebIDL.  

Allen

Received on Friday, 10 August 2012 20:11:43 UTC