Arguments and formal parameters aliasing

liorean liorean at gmail.com
Sat Sep 27 19:22:16 PDT 2008


Hello!

I just noticed an inconsistency between the ES3 spec and browsers that
I've not seen discussed before. At the moment I'm on my iBook, so
these are not the most recent browsers, but they include ie5.2m, ff2,
saf1.3 and op9.5.


    function fn(a, b, c, d, a, b, c, e){
        arguments[7]='e';
        b='g';
        return [
            'a: '+a+'  arg0: '+arguments[0],
            'b: '+b+'  arg1: '+arguments[1],
            'c: '+c+'  arg2: '+arguments[2],
            'd: '+d+'  arg3: '+arguments[3],
            'a: '+a+'  arg4: '+arguments[4],
            'b: '+b+'  arg5: '+arguments[5],
            'c: '+c+'  arg6: '+arguments[6],
            'e: '+e+'  arg7: '+arguments[7]]
                .join('\r\n');
}

fn('a','b','c','d','e','f');

Results from ff2, op5 and ie5.2m are:
    a: e  arg0: a
    b: g  arg1: b
    c: undefined  arg2: c
    d: d  arg3: d
    a: e  arg4: e
    b: g  arg5: g
    c: undefined  arg6: undefined
    e: undefined  arg7: e

Results from saf1.3 are:
    a: e  arg0: a
    b: g  arg1: b
    c: undefined  arg2: c
    d: d  arg3: d
    a: e  arg4: e
    b: g  arg5: f
    c: undefined  arg6: undefined
    e: undefined  arg7: e

I haven't been able to test this since I'm not on a windows machine,
but IIRC Chrome will alias e and arg7 but otherwise behave like
moz/op/ie. I also suspect that later saf versions than 1.3 will
correctly alias b with arg5.



The ES3 spec has the following to say about this:
~~~~<10.1.3 Variable Instantiation>~~~~
...
 •  For function code: for each formal parameter, as defined in the
FormalParameterList, create a property of the  variable object whose
name is the Identifier and whose attributes are determined by the type
of code. The values  of the parameters are supplied by the caller as
arguments to [[Call]]. If the caller supplies fewer parameter values
than there are formal parameters, the extra formal parameters have
value undefined. If two or more formal  parameters share the same
name, hence the same property, the corresponding property is given the
value that  was supplied for the last parameter with this name. If the
value of this last parameter was not supplied by the  caller, the
value of the corresponding property is undefined.
...
~~~~</>~~~~
In other words saying that two formal parameters with the same
identifier are the same variable, and that the last one in the
parameter list will be the one giving the variable a value.
~~~~<10.1.8 Arguments Object>~~~~
...
 •  For each non-negative integer, arg, less than the value of the
length property, a property is created with name  ToString(arg) and
property attributes { DontEnum }. The initial value of this property
is the value of the  corresponding actual parameter supplied by the
caller. The first actual parameter value corresponds to arg = 0,  the
second to arg = 1, and so on. In the case when arg is less than the
number of formal parameters for the  Function object, this property
shares its value with the corresponding property of the activation
object. This  means that changing this property changes the
corresponding property of the activation object and vice versa.
~~~~</>~~~~
And this says that each argument sent is aliased to the corresponding
formal parameter's variable. Given the behaviour of several parameters
with identical identifier earlier, and no exception being given for
this case, I can only read this as meaning that the browser
implementations go contrary to the ES3 spec regarding arg0, arg1 ,
arg2 and the a, b and c variables not being being aliased. It seems
the browser scripting engines only alias the last argument
corresponding to any given formal parameter identifier with the
corresponding variable, even though these are supposed to be the same
variable.


Something to address in ES3.1, given at least three, probably four
implementors disagree with the ES3 spec?
-- 
David "liorean" Andersson


More information about the Es-discuss mailing list