On 11 May 2011 20:30, Mark S. Miller <erig...@google.com> wrote: > > On Wed, May 11, 2011 at 10:31 AM, Andreas Rossberg <rossb...@google.com> > wrote: >> >> On 11 May 2011 18:31, Mark S. Miller <erig...@google.com> wrote: >> > On Wed, May 11, 2011 at 4:42 AM, Andreas Rossberg <rossb...@google.com> >> > wrote: >> >> >> >> Thanks to everybody for clearing up my confusion. The thing I had >> >> missed in the spec was Section 10.4.2. And of course, my example was >> >> too simplistic because it couldn't distinguish caller and global >> >> context. >> >> >> >> At the risk of reviving old discussions, are there any sources >> >> explaining the rationale behind the current design? The "obvious" >> >> solution to me would have been having two internal variants/modes of >> >> (or "entry points" to) the eval function, one strict, one non-strict. >> >> And depending on the lexical strict mode, the identifier "eval" would >> >> be bound to the right one. >> > >> > I don't think I understand the suggestion. What would the following code >> > do: >> > // non-strict outer context >> > function f(eval) { >> > var f = eval; >> > function g() { >> > "use strict"; >> > eval(str); // [1] >> > (1,eval)(str); // [2] >> > f(str); // [3] >> > } >> > } >> > [1] If the outer eval is bound to the global eval function then this is >> > a >> > direct eval, which therefore lexically inherits strictness. So no >> > problem >> > here. >> > [2] The 'eval' identifier is bound in non-strict code and used in strict >> > code. >> > [3] Strict code makes no use here of a lexical binding of the identifier >> > "eval". >> > >> > A previous approach which we rejected was to make strictness dynamically >> > scoped, so all three of the above calls would do strict evals. This was >> > rejected to avoid the problems of dynamic scoping. Are you suggesting a >> > rule >> > that would affect #2 but not #3? If so, IIRC no such rule was previously >> > proposed. >> >> I'm actually suggesting plain lexical scoping. :) >> >> Basically, what I'm saying is that the directive "use strict" could >> simply amount to shadowing the global eval via an implicit "var eval = >> eval_strict" (unless global eval has already been shadowed lexically). >> So all uses of the identifier `eval' in that scope would refer to its >> strict version, no matter when, where, or how you ultimately invoke >> it. Consequently, all your three examples would behave the same, only >> depending on the argument to f. > > I don't understand. If "use strict" implicitly introduces a "var eval = > eval_strict;" at the position it occurs, then wouldn't #3 in my example > still evaluate non-strict?
Assume that - we distinguish two variants of the eval function, strict and non-strict -- let's call these values EVAL_s and EVAL_ns. - initially (in global scope), the identifier `eval' is bound to EVAL_ns. - in a strict mode scope it will be considered rebound to EVAL_s instead (unless it has already been shadowed by user code anyway). (In addition, at least in strict mode, the only calls to `eval' that are considered _direct_ calls would be those where `eval' statically refers to the initial binding or one of the implicit strict-mode rebindings -- i.e., where it has not been shadowed by the user.) In your example, the `eval' identifier is already shadowed by the function parameter, so the inner "use strict" would have no effect on it -- in that scope `eval' is just an ordinary identifier. Consequently, all 3 examples would behave alike and are non-direct calls. Whether strict or not solely depends on what you pass in to f: // non-strict scope f(eval) // EVAL_ns (function() { "use strict"; f(eval) })() // EVAL_s f((function() { "use strict"; return eval })()) // EVAL_s Does that make sense? The idea is that strict/non-strict is resolved w.r.t. the static scope where the identifier `eval' occurs. With this semantics, there would be no way in strict mode to access non-strict eval, unless it is explicitly provided by someone. With the current rules that is not the case, because you can easily defeat strict mode by a random indirection, e.g.: "use strict"; var e = eval e("var oops = 666") // pollutes the global object, although the whole program is in strict mode I'm not sure whether that was intentional or not, but it feels strange. /Andreas _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss