Closed Bug 69441 Opened 24 years ago Closed 24 years ago

function f(o,s,x) {with(o) eval(s); return z;} not parsing correctly

Categories

(Rhino Graveyard :: Core, defect)

x86
Windows NT
defect
Not set
normal

Tracking

(Not tracked)

VERIFIED INVALID

People

(Reporter: pschwartau, Assigned: rogerl)

Details

This is the Rhino version of bug 68498 against SpiderMonkey. 
The following testcase (created by Brendan) is failing on Rhino: 

            js/tests/js1_5/Regress/regress-68498-004.js


FAILED!: Testing self.eval(str) inside a function; currently at statement 1 
FAILED!: Expected value 'undefined', Actual value 'number'


Here is the core of the testcase:

/*
* "ECMA-262 Edition 3, 10.1.3 requires a FunctionDeclaration parsed as part 
* of  a Program by eval to create a property of eval's caller's variable object.
* This test evals in the body of a with statement, whose scope chain is not
* relevant to the effect of parsing the FunctionDeclaration."
*/

var summary = 'Testing self.eval(str) inside a function';
var sToEval='';
var actual=[ ];
var expect=[ ];


// Capture a reference to the global object -
var self = this;

// You shouldn't see this global variable's value in any printout -
var x = 'outer';

// This function is the heart of the test - 
function f(o,s,x) {with(o) eval(s); return z;};


// Run-time statements to pass to the eval inside f
sToEval += 'actual[0] = typeof g;'
sToEval += 'function g(){actual[1]=(typeof w); return x};'
sToEval += 'actual[2] = w;'
sToEval += 'actual[3] = typeof g;'
sToEval += 'var z=g();'


// Set the actual-results array. The next line sets actual[0] - actual[4]
actual[4] = f({w:44}, sToEval, 'inner');
actual[5] = 'z' in self && z;


// Set the expected-results array.
expect[0] = 'function';
expect[1] = 'undefined';
expect[2] = 44;
expect[3] = 'function';
expect[4] = 'inner';
expect[5] = false;



We have expect[1]='undefined' because per ECMA, the scope chain of the 
with block is not supposed to be relevant when the FunctionDeclaration 
is parsed. (Brendan, do I have that right? )


But Rhino is giving actual[1]='number'
ECMA-262 Edition 3:

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. 

· For each FunctionDeclaration in the code, in source text order, create a 
property of the variable object whose name is the Identifier in the 
FunctionDeclaration, whose value is the result returned by creating a Function 
object as described in section 13, and whose attributes are determined by the 
type of code. If the variable object already has a property with this name, 
replace its value and attributes. Semantically, this step must follow the 
creation of FormalParameterList properties. 

· For each VariableDeclaration or VariableDeclarationNoIn in the code, create 
a property of the variable object whose name is the Identifier in the 
VariableDeclaration or VariableDeclarationNoIn, whose value is undefined 
and whose attributes are determined by the type of code. If there is already 
a property of the variable object with the name of a declared variable, the 
value of the property and its attributes are not changed. Semantically, this 
step must follow the creation of the FormalParameterList and FunctionDeclaration 
properties. In particular, if a declared variable has the same name as a 
declared function or formal parameter, the variable declaration does 
not disturb the existing property.
 
Argh!  Sleep-deprived me is wrong.  ECMA 13.2 says that the scope chain of the
execution context in which a FunctionDeclaration is parsed *is* relevant to the
function object -- specifically, it induces the value of the function object's
[[Scope]] internal property.

Phil, this bug is invalid, and the testcase needs to be revised so that
expected[1] is 'number'.  And SpiderMonkey needs a bug reporting the revised
testcase failure.

There are two independent objects relevant to a named function declaration: the
object in which the function object is stored as the property value identified
by the function's name (this is the variable object, never affected by a with
statement); and the scope chain, a list of objects that goes through the
variable object, but does not necessarily start with it (this chain becomes the
value of the [[Scope]] internal property of the function object).

The reference in g to (typeof w) should search the activation of g's scope
chain, which is [Call(g), With(o), Call(f), global].  So (typeof w) should
evaluate to 'number', because o.w is a number.  But g should be defined as a
property of the variables object, which is Call(f).  And it must be defined
early, hence expected[0] and expected[3].

Sorry about this blunder.  I wish I had never put with statements in the silly
language!  Of course, it's pretty clear that no one cares in the real world.
Phil, hit me with a bug and I'll fix the relevant bytecode cases in jsinterp.c.
 Thanks,

/be
Status: NEW → RESOLVED
Closed: 24 years ago
Resolution: --- → INVALID
Marking Verified Invalid - 
Status: RESOLVED → VERIFIED
I have filed bug 69559 against SpiderMonkey, and modified the above 
testcase to read as follows: 


actual[1]=(typeof w == "undefined" || w)
expect[1] = 44
You need to log in before you can comment on or make changes to this bug.