Disable global name analysis with var declarations inside with (bug 585524, r=dmandelin).

This commit is contained in:
David Anderson 2010-11-23 18:00:39 -08:00
parent 4aa2614c7f
commit 9eb213e3fb
4 changed files with 24 additions and 9 deletions

View File

@ -0,0 +1,11 @@
function f() { return 2; }
function g(o) {
with (o) {
var f = function() { return 4; }
}
return f();
}
assertEq(g({}), 4);

View File

@ -2273,7 +2273,7 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
* JSOP_DEFFUN could introduce a shadowing definition, so if it
* is present, we can't optimize to JSOP_GETGLOBAL.
*/
if (cg->hasDefFun())
if (cg->mightAliasLocals())
return JS_TRUE;
switch (op) {

View File

@ -252,9 +252,12 @@ struct JSStmtInfo {
#define TCF_COMPILE_FOR_EVAL 0x2000000
/*
* The function contains a JSOP_DEFFUN bytecode.
* The function has broken or incorrect def-use information, and it cannot
* safely optimize free variables to global names. This can happen because
* of a named function statement not at the top level (emitting a DEFFUN),
* or a variable declaration inside a "with".
*/
#define TCF_FUN_HAS_DEFFUN 0x4000000
#define TCF_FUN_MIGHT_ALIAS_LOCALS 0x4000000
/*
* Flags to check for return; vs. return expr; in a function.
@ -272,7 +275,7 @@ struct JSStmtInfo {
TCF_FUN_USES_OWN_NAME | \
TCF_HAS_SHARPS | \
TCF_FUN_CALLS_EVAL | \
TCF_FUN_HAS_DEFFUN | \
TCF_FUN_MIGHT_ALIAS_LOCALS | \
TCF_FUN_MUTATES_PARAMETER | \
TCF_STRICT_MODE_CODE)
@ -403,12 +406,12 @@ struct JSTreeContext { /* tree context for semantic checks */
return flags & TCF_FUN_CALLS_EVAL;
}
void noteHasDefFun() {
flags |= TCF_FUN_HAS_DEFFUN;
void noteMightAliasLocals() {
flags |= TCF_FUN_MIGHT_ALIAS_LOCALS;
}
bool hasDefFun() const {
return flags & TCF_FUN_HAS_DEFFUN;
bool mightAliasLocals() const {
return flags & TCF_FUN_MIGHT_ALIAS_LOCALS;
}
void noteParameterMutation() {

View File

@ -3143,7 +3143,7 @@ Parser::functionDef(JSAtom *funAtom, FunctionType type, uintN lambda)
* sub-statement.
*/
op = JSOP_DEFFUN;
outertc->noteHasDefFun();
outertc->noteMightAliasLocals();
}
funbox->kids = funtc.functionList;
@ -3608,6 +3608,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
if (stmt && stmt->type == STMT_WITH) {
data->fresh = false;
pn->pn_dflags |= PND_DEOPTIMIZED;
tc->noteMightAliasLocals();
return true;
}