In what ways does the following "eval" regularity break?

Brendan Eich brendan at mozilla.com
Thu Oct 30 13:09:41 PDT 2008


On Oct 30, 2008, at 12:58 PM, Maciej Stachowiak wrote:

> On Oct 30, 2008, at 12:24 PM, Brendan Eich wrote:
>
>> Probably when we started, we had the Firefox 1.0-1.5 behavior  
>> (JS1.5-1.6) in mind. Since then, elves "fixed" bugs. :-/
>>
>> Still I do not know of web content that calls indirect eval and  
>> expects local eval. Gmail did (and may still) due to its cruncher  
>> do something like
>>
>> var Ae = eval;... Ae(s)
>>
>> but the program in string s wanted only global scope.
>
> We have not found compatibility issues since we converted indirect  
> eval to global eval in WebKit. (We have about 10,000 regular nightly  
> users so it's had some test coverage, but that is still a fair bit  
> less than a public beta or a full release version.) I believe what  
> we have now matches the old proposed ES4 behavior.
>
> Brendan, do you know if the Mozilla change on this was for reasons  
> of Web compatibility?

Not exactly. I believe the change was an unintended consequence of  
fixing a series of bugs that did not explicitly request that indirect  
eval be local. These bugs involved, e.g. Prototype (the JS library)  
and its Ajax.Updater (with evalScripts set to true). The code in  
question used Prototype's forEach. A javascript: URL reduction:

javascript: (function xxx(){ ["var x"].forEach(eval); })();

As I wrote in another post today, we would gladly go back to the  
JS1.5-1.6-era indirect-eval-is-global behavior if it were  
standardized. We would not be glad about any standard that required  
indirect eval to be "operator eval". No doubt you feel the same way!

/be

>
>
> Regards,
> Maciej
>
>>
>>
>>
>>> The
>>> specification of indirect eval was also discussed in this morning's
>>> ES3.1 phone call. Based on the ES3 spec and a quick testing of the
>>> browsers, as well as the memory of those who had an opinion about  
>>> this
>>> in Redmond, we've been proceeding with the assumption that the ES3
>>> spec should be read as:
>>>
>>> An implementation may implement an indirect eval either by  
>>> throwing an
>>> EvalError or by treating it as equivalent to the eval operator.
>>
>> This is not what we want, either as implementors or JS users.  
>> Implementors in particular have to deoptimize at runtime based on  
>> the eval built-in being invoked by some random name, in an  
>> environment that the compiler optimized assuming no eval call.  
>> Users cannot easily reason about hidden eval calls.
>>
>>
>>> Testing on FF3.0.3 and FF3.1Beta, with and without TraceMonkey
>>> enabled, seemed to bear this out:
>>>
>>>  function foo(a, b, c) { return b(c); }
>>>  foo(3, eval, 'a'); // yields 3
>>>  foo(3, window.eval, 'a'); // yields 3
>>
>> Try Firefox 1 or 1.5. (Damn elves.... :-)
>>
>> BTW, did you test V8?
>>
>>
>>> However, a bit more testing reveals something truly bizarre:
>>>
>>>  window.a = 'x';
>>>  foo(3, window.eval, 'a') // yields 'x'
>>>  foo(3, eval, 'a'); // yields 'x'
>>>
>>> I can't think of any semantics that would account for both  
>>> behaviors.
>>> Is this a bug?
>>
>> No, it is ancient pre-ECMA magic. The indirect case where eval was  
>> referenced from the global (window) object adds an implicit with  
>> (window). So
>>
>> return b(c);
>>
>> becomes
>>
>> with (window) return eval('a');
>>
>> We've kept compatibility here for over a decade, but we're more  
>> than willing to break it for a standard that says how indirect eval  
>> should work.
>>
>> /be
>> _______________________________________________
>> Es-discuss mailing list
>> Es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>



More information about the Es-discuss mailing list