Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Gecko's Javascript interpreter engine semantics?

Edit

In consideration of the answer response below regarding the reference ECMAScript Language Specification - 11.13.2 Compound Assignment

Considering why these,

javascript:
   o="";  o = o + (o+=1)    ; alert(o);
   o="";  o =     (o+=1) + o; alert(o);

are NOT the same. There are temporal semantic issues with left to right script evaluation (ref:ECMA spec. - The addition operator). One consequence is that the + operator is not necessarily commutative.

This can also be seen by with:

javascript:
   o=1;  o = o + (o+=1)    ; alert(o);
   o=1;  o =     (o+=1) + o; alert(o);

or

javascript:
   o=" _ ";  o = o + (o+=1)    ; alert(o);
   o=" _ ";  o =     (o+=1) + o; alert(o);

The lazy evaluation paradigm, erroneously and inappropriately used by me thereby creating the problem below, is also a bad attribute of my personal modus operandi.


Original Post

The following considerations may already have been addressed, though it seems not. If so, could links to the discussions be provided?

The formal denotational semantics of the Gecko Javascript runtime engine are an enigma. Empirical testing is exhausting and cannot be exhaustive.

  • Is there available an authoritative formal specification or official reference defining exactly how Gecko interprets Javascript?

The reference, ECMAScript Language Specification, seems inadequate, though credence is provided for the concoction of such scripts like,

javascript: alert( function(){return {}}().life=42 )

with the consequent meaning of such constructs when binding values.

  • Is there a definitive paradigm describing the Javascript code interpretation for object and instance evaluation?

This would clarify the concepts of call by (or rather use by) need, value, reference, inference, name, ... as relevant or not. That, Javascript is a prototyping interpreter, gives implicit meaning to some of the issues below.

What is the expected result of:

javascript: o={n:0}; f=function(){o.n+=1; return 10};
   alert([
      o.n,            f(),
      o.n,       o.n+=f(),
      o.n, eval('o.n+=f()'), 
      o.n, eval('o.n+='+f()),
      o.n,
   ].join(",\t"));

? Is it easy to predict the results (correctly!)?

The question is a bit rhetorical since it was specifically contrived with eval's to coerce and emphasize the subtle nuances of the interpretation. Can the evaluation of this script (and the aside below) be resolved with either, the ECMAScript Language Specification or another document, alluded to earlier?

(As an aside, consider:

javascript: ra=[];
   alert([
      ra, ra[ra.length]=" partially defined.",
      ra, ra.push("\n RA is not shown"),
      ra, ra.reverse()[42],
   ].join(",\t\t"));

which displays:

 RA is not shown, partially defined.,        partially defined.,        
 RA is not shown, partially defined.,       2,      
 RA is not shown, partially defined.,       

where the partial evaluations of ra are NOT analogous to o.n's!

and the following which is less exotic than using o.n:

javascript: o=""; f=function(){o+=1; return 0};
   alert([
      o,          f(),
      o,       o+=f(),
      o, eval('o+=f()'), 
      o, eval('o+='+f()),
      o,
   ].join(",\t"));

which displays:

,   0,  1,  10, 10, 100,    100,    10010,  10010

)

Considering the following script:

javascript:
   asn="\t\t and so now,\t o.n is "; nl="\n\n";
   o={}; f=function(){o.n+=1; return 10};
   alert(["Using:\n",window.navigator.userAgent,
   nl,"The function f() is:\n ",f,
   nl,"What the!!?!? \t\t\t\t\t\t\t initially \t\t o.n is ",          o.n = 0,
 nl,"Called as a procedure: \t\tf() is ", f(),                   asn, o.n,
nl,"but, instead of 12 \t\to.n+=f() is ", o.n+=f(),              asn, o.n,
     nl,"however eval'd\t\to.n+=f() is ", eval("o.n+="+f()),     asn, o.n,
    "!\n\nIt makes no functional difference if, instead of o.n, o['n'] is used.",
    "\nThe expected o.n evaluation sequence is 0, 1, (+1+10=) 12, (+1+10=) 23.",
    "\n_____ _____ _____ _____ _____ _____ _____ _____^^ missing in result",
  ].join(""));

The Gecko engine outputs:

Using:
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3)
        Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3

The function f() is:
 function () {
    o.n += 1;
    return 10;
}

What the!!?!?                                initially       o.n is 0

Called as a procedure:      f() is 10        and so now,     o.n is 1

but, instead of 12      o.n+=f() is 11       and so now,     o.n is 11

however eval'd          o.n+=f() is 22       and so now,     o.n is 22!

It makes no functional difference if, instead of o.n, o['n'] is used.
The expected o.n evaluation sequence is 0, 1, (+1+10=) 12, (+1+10=) 23.
_____ _____ _____ _____ _____ _____ _____ _____^^ missing in result
like image 902
Ekim Avatar asked Apr 16 '11 20:04

Ekim


1 Answers

JavaScript has an eager evaluation (call by value) execution model clearly spelled out in the ECMA standard. All of these questions can be resolved by carful reading of the standard. For example, the reason why the result is 11 above and not 12 is clearly spelled out in 11.13.2 of the standard. o.n is evaluated prior to the call to f() not after as specified by step 2.

like image 71
chuckj Avatar answered Nov 12 '22 17:11

chuckj