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.