In what ways does the following "eval" regularity break?
Brendan Eich
brendan at mozilla.com
Thu Oct 30 12:24:17 PDT 2008
On Oct 30, 2008, at 10:20 AM, Mark S. Miller wrote:
> On Thu, Oct 30, 2008 at 8:35 AM, Brendan Eich <brendan at mozilla.com>
> wrote:
>> [...] Browser intersection semantics make indirect eval global, [...]
>
> I had hoped so. This came up at Redmond, and unfortunately, without
> either you or Lars there, I was unable to reconstruct why we thought
> it would be upwards compatible to make indirect eval global.
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.
> 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
More information about the Es-discuss
mailing list