Assigning to globals in strict mode

Allen Wirfs-Brock Allen.Wirfs-Brock at microsoft.com
Tue Oct 19 22:13:11 PDT 2010


>"use strict"; undeclared = global.undeclared = 5;
>This is allowed by ES5 strict.

I don't think so:

For the outer (leftmost) assignment operator the parse is
  LeftHandSideExpression: undeclared
  AssignmentExpression: parse of (global.undeclared = 5)

11.13.1
step 1 creates lref as a reference to 'undeclared'. It is a unresolved reference.  Its base value is undefined.
step 2 creates rref by evaluating the AssignmentExpresion.  It will be the value 5. 
Step 3 assigns the value of GetValue(5) to rval.  It is still the value 5.
Step 4 does nothing because the name of lref is neither "eval" or "arguments"
Step 5 calls PutValue(lref,5)
8.7.2 PutValue
Step 3  V (the value of lref) is found to be an UnresolvedReference because its vase value is undefined.
Step 3.a.i throws a ReferenceError because V is a strict mode Reference.

If this seems consistent with what Brendan describes as the ES1 behavior: " ES1 on were careful to avoid evaluating the RHS of assignment before binding the LHS, that is, finding the Reference base object in which the LHS property name would be bound.".  The LHS, undeclared, was determined to  be unbound before the  RHS side was evaluated.  Because of that determination a strict mode effort is being thrown.

However this also means that: "use strict";  this.x = 1;  x = delete this.x;
recreates the global property x after first deleting it. .  For the assignment containing the delete, lref is a resolved reference to x with the global environment record as its base.  The delete actual does delete the global property named x.  Then step 5 of 11.31.1 does a PutValue(lref,true).    Lref is still a resolved reference (that was determined in step 1 of 11.13.1 before the delete) so step 5.1 calls the SetMutableBinding ('x', true, true) methods of the global environment record p.
That calls the [[Put]] internal method of the global objects passing ('x',true,true).  This calls [[DefineOwnProperty]] which in step 4.a.i will recreate the property 'x' of the global object with the value true.

The delete behavior really seems unfortunate for strict mode but it isn't clear that it is easy to correct if that is desired.  It would probably require an extra step in 10.2.1.1.3

Allen


> -----Original Message-----
> From: Brendan Eich [mailto:brendan at mozilla.org]
> Sent: Tuesday, October 19, 2010 8:37 PM
> To: Allen Wirfs-Brock
> Cc: Maciej Stachowiak; Mark S. Miller; es5-discuss es5-discuss at mozilla.org
> Subject: Re: Assigning to globals in strict mode
> 
> On Oct 19, 2010, at 6:07 PM, Allen Wirfs-Brock wrote:
> 
> > I'm here but trying, to sort out what, if any the issues are and there are so
> many messages to plow through.  Could somebody relist the specific issues or
> questions of concern.   BTW, harmony issues are all speculative at this time.  The
> only standard we have is ES5 that that is the one we need to be conforming to
> (or identify any real errors).
> 
> 
> I think (reviewing the thread myself) that the only issue, now that everyone is
> clear on ES5 requiring that the check for an assignment expression creating a
> global variable happen after the RHS of assignment is evaluated, is exactly the
> order of evaluation, because the RHS evaluation can affect the scope chain:
> 
> "use strict"; undeclared = global.undeclared = 5;
> 
> This is allowed by ES5 strict.
> 
> ES1 on were careful to avoid evaluating the RHS of assignment before binding
> the LHS, that is, finding the Reference base object in which the LHS property
> name would be bound.
> 
> Jason points out that ES5 is clear enough on this point, and he argues
> (convincingly in my opinion) that we shouldn't try to check before RHS
> evaluation, since PutValue and [[DefineOwnProperty]] both need to check after
> anyway.
> 
> So there's arguably no bug for ES5. Possibly you see a problem, or a solution
> that doesn't duplicate the check before and after RHS evaluation?
> 
> For Harmony, speculation is almost the best we can do since the future isn't here
> yet, but I think it's important to form tentative normative agreements or
> aspirations. IMHO we have pretty strong agreement to fix scoping to be static
> all the way up. This came out at the last f2f.
> 
> So, it doesn't seem to me that "anything goes" -- there is no chance, for
> example, that we'll *add* dynamically scoped constructs or opt-in modes ;-).
> Our aspirations or stronger positions all favor static scoping everywhere
> (including the top-level scope, which would not be an object declarative
> environment), now that ES5 strict removes 'with' and tames direct eval.
> 
> We should spec this in more detail and prototype it, of course. But along with
> this "lexical scope" goal, we have talked specifically about early errors for free
> variable uses and assignments.
> 
> This came up now because, as Maciej suggested, we don't want different
> runtime semantics between ES5 strict and Harmony (which is based on ES5
> strict). If the agreements or aspirations that I've described hold for Harmony,
> then there's no such conflict: Harmony never lets such a program reach runtime.
> 
> /be
> 
> >
> > Allen
> >
> >> -----Original Message-----
> >> From: es5-discuss-bounces at mozilla.org [mailto:es5-discuss-
> >> bounces at mozilla.org] On Behalf Of Maciej Stachowiak
> >> Sent: Tuesday, October 19, 2010 5:54 PM
> >> To: Brendan Eich
> >> Cc: Mark S. Miller; es5-discuss es5-discuss at mozilla.org
> >> Subject: Re: Assigning to globals in strict mode
> >>
> >>
> >> On Oct 19, 2010, at 5:36 PM, Brendan Eich wrote:
> >>
> >>> On Oct 19, 2010, at 4:22 PM, Oliver Hunt wrote:
> >>>
> >>>> On Oct 19, 2010, at 4:19 PM, Maciej Stachowiak wrote:
> >>>>
> >>>>> If Harmony is going to require the other behavior, how about an
> >>>>> erratum to
> >> make ES5 strict mode the same? There doesn't seem to be much reason
> >> to have a future behavior difference here.
> >>>>
> >>>> In harmony you have a purely lexical scope, eg. the global object
> >>>> is not at the
> >> head of the scope chain.  That means all unqualified names can be
> >> resolved statically so all these errors become early errors.
> >>>>
> >>>> In ES5 there is both with() and the global object that make early
> >>>> errors
> >> incompatible.
> >>>
> >>> Exactly. (BTW, do people use "head" for the far end of the scope
> >>> chain? I try to
> >> be consistent in using "tail", myself... ;-)
> >>>
> >>> Plus, ES5 is "done". Sure, there are errata and will be more. But
> >>> too many
> >> errata, especially "big" ones (even if "small" in spec language
> >> terms; I mean by "big" that they have significant implications for
> >> implementors and possibly for other parts of the spec, without enough
> >> time to study the big picture), seem likely to cause trouble.
> >>
> >> Just to make sure I'm clear on this, will the following program have
> >> the same effect in ES5 strict mode and Harmony, or no?
> >>
> >> "use strict";
> >> var declared = 0;
> >> undeclared = declared++;
> >>
> >> My understanding is that in ES5 strict mode, declared ends up 1, but
> >> in Harmony it ends up 0. In both cases, undeclared is left undefined.
> >> Is that correct? Or maybe by "early error" you mean it's a parse
> >> error and therefore in Harmony, declared will not be defined at all.
> >>
> >> Regards,
> >> Maciej
> >>
> >> _______________________________________________
> >> es5-discuss mailing list
> >> es5-discuss at mozilla.org
> >> https://mail.mozilla.org/listinfo/es5-discuss
> >
> 



More information about the es5-discuss mailing list