eval

Lars Hansen lhansen at adobe.com
Thu Mar 6 14:25:12 PST 2008


> -----Original Message-----
> From: es4-discuss-bounces at mozilla.org 
> [mailto:es4-discuss-bounces at mozilla.org] On Behalf Of Geoffrey Garen
> Sent: 5. mars 2008 19:26
> To: es4-discuss Discuss
> Subject: eval
> 
> Hi all.
> 
> I'm trying to implement an ES4-compliant version of eval, but 
> I'm having trouble understanding what the specified behavior is.
> 
> In ES4,
> 
>      eval(x)
> 
> is distinct from all of
> 
>      window.eval(x)
> 
>      eval.call(myThisObject, x)
> 
>      frames[0].eval(x)
> 
> in that the first form is an operator, and the last three 
> forms are function calls.
> 
> Right?

Yes.  This is a function call form too:

  w = eval
  w(x)

(Note that only the operator form is required by the ES3 spec.)

> OK, for the eval operator, the eval function, the eval 
> function called with a specified 'this' object, and the eval 
> function called on another global object, respectively:
> 
> What scope chain should be used?
> 
> What variable object should be used?
> 
> What value should 'this' take on?
> 
> What gets called if window.eval has been overridden, as in (at global
> scope):
> 
> eval = function() { return "overridden"; } eval(x);
> 
> or
> 
> window.eval = function() { return "overridden"; } window.eval(x);
> 
> What gets called if the "eval" identifier has been shadowed 
> by a variable in scope, as in:
> 
> with({ eval: function() { return "overridden"; } }) {
> 	eval(x);
> }
> 
> or
> 
> try {
> 	throw function() { return "overridden"; }; } catch(eval) {
> 	eval(x);
> }
> 
> ?

In my opinion the following is roughly right:

obj.eval(x)
  if eval is the original global eval function then
    if obj is an ES global object (window, frame) then
      invoke eval as follows:
        the scope chain holds that window (global) object only
        the variable object is that window object
        the value of "this" is that window object  
    else
      this is an error
  else
    we don't care; invoke the method eval on obj

eval(x)
  look up "eval"
  if the found value v is the original eval function and
     the binding object x holding eval is an ES global object and
     the global object on the scope chain for v is x then
       invoke eval as follows:
         the scope chain is the lexical chain in effect at the point of
invocation
         the variable object is the innermost variable object in effect
(which is to
             say that it excludes binding objects introduced for "let",
"catch", named
             function expressions, "switch type", and note also that
code at the top
             level of a class is static initialization code so the
variable object
             is the global object)
         the value of "this" is the global object x
  else
    we don't care; invoke v as a normal function

Note a couple of things.  In the case obj.eval(x) all the logic can be
moved into the eval function itself, and in the case of a "masquerading
eval" as I showed earlier that is exactly what you want too.  Also, to
handle eval(x) the generated code needs to look roughly like what's
outlined above, ie, it becomes a wee bit bulky.  Probably not a problem
in practice.

--lars



More information about the Es4-discuss mailing list