Closed Bug 124900 Opened 23 years ago Closed 23 years ago

arguments object storing duplicate parameter values

Categories

(Rhino Graveyard :: Core, defect)

x86
All
defect
Not set
normal

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: pschwartau, Assigned: norrisboyd)

Details

The testcase

           js/tests/ecma_3/ExecutionContexts/10.1.3-1.js

has recently been added to the JS testsuite, to test functions having
duplicate formal parameter names. The following section of the test
is passing in SpiderMonkey, but failing in Rhino:


function f(x,x,x,x)
{
  var ret = [];

  for (var i=0; i<arguments.length; i++)
    ret.push(arguments[i]);

  return ret.toString();
}

actual = f(1,2,3,4);
expect = '1,2,3,4';


SPIDERMONKEY
test passes

RHINO
test FAILED!: Expected value '1,2,3,4', Actual value '4,4,4,4'



ECMA-262, 3rd Edition Final, contains this language:


10.1.3 Variable Instantiation 
Every execution context has associated with it a variable object.
Variables and functions declared in the source text are added as properties
of the variable object. For function code, parameters are added as properties
of the variable object. 

Which object is used as the variable object and what attributes are used
for the properties depends on the type of code, but the remainder of the
behaviour is generic. On entering an execution context, the 
properties are bound to the variable object in the following order: 

• 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. 
  
  

10.1.8 Arguments Object 
When control enters an execution context for function code, an arguments object
is created and initialised as follows: 

• The value of the internal [[Prototype]] property of the arguments object
is the original Object prototype object, the one that is the initial value of
Object.prototype (see 15.2.3.1). 

• A property is created with name callee and property attributes { DontEnum }.
The initial value of this property is the Function object being executed.
This allows anonymous functions to be recursive. 

• A property is created with name length and property attributes { DontEnum }.
The initial value of this property is the number of actual parameter values
supplied by the caller. 

• 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.
My reading of ECMA is that disparate parameter values should be preserved
in the arguments object, even if the parameter names are the same in each case,
and even though it is only the last parameter value that will have effect.

cc'ing Waldemar to be sure -
So this behavior is correct, right?

js> function f(x,x) { x = 7; return arguments[0]; }
js> f(3,4)
7
js> function f(x,x) { x = 7; return arguments[1]; }
js> f(3,4)
7
Comment 2: I agree.

Comment 3: I'd expect, in a faithful ECMA implementation, the first function
definition to return 3 and the second one to return 7.  If they both return 7,
you get a nonsensical situation of x being an alias of arguments[0], x being an
alias of arguments[1], but arguments[0] and arguments[1] initially holding
different values.

As an aside, I personally feel that the standard is unnecessarily detailed about
this case and should have left it unspecified.  Having two parameters with the
same name is not something ECMAScript programs should do.
Here's what SpiderMonkey does on Norris' example:

js> function f(x,x) {x=7; return arguments[0]}
js> f(3,4);
3

js> function f(x,x) {x=7; return arguments[1]}
js> f(3,4);
7
I wish I knew why MS's lead was so intent on making this case work, and making
the spec for it so detailed.  It seems to be gilding the lily, at best.  I tried
pushing for SpiderMonkey's behavior (an error, now a strict warning), but lost
no good reason.

/be
Fixed:

Checking in Arguments.java;
/cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/Arguments.java,v  <-- 
Arguments.java
new revision: 1.13; previous revision: 1.12
done
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Verified Fixed. Both new testcases on duplicate parameters are now
passing in the rhino and rhinoi shells on WinNT: 

           js/tests/ecma_3/ExecutionContexts/10.1.3-1.js
           js/tests/ecma_3/ExecutionContexts/10.1.3-2.js
Status: RESOLVED → VERIFIED
Targeting as resolved against 1.5R4
Target Milestone: --- → 1.5R4
You need to log in before you can comment on or make changes to this bug.