Bug 1145491 part 1. Only do the fast path for JSOP_BINDGNAME when the script doesn't have a polluted global. r=luke,jandem

This commit is contained in:
Boris Zbarsky 2015-03-20 21:34:18 -04:00
parent cc4f3b16cb
commit b596d465cd
6 changed files with 35 additions and 22 deletions

View File

@ -6898,7 +6898,7 @@ EmitLexicalInitialization(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode
return false;
if (pn->getOp() != JSOP_INITLEXICAL) {
bool global = js_CodeSpec[pn->getOp()].format & JOF_GNAME;
bool global = IsGlobalOp(pn->getOp());
if (!EmitIndex32(cx, global ? JSOP_BINDGNAME : JSOP_BINDNAME, atomIndex, bce))
return false;
if (Emit1(cx, bce, JSOP_SWAP) < 0)

View File

@ -2088,8 +2088,12 @@ BaselineCompiler::emit_JSOP_GETGNAME()
bool
BaselineCompiler::emit_JSOP_BINDGNAME()
{
frame.push(ObjectValue(script->global()));
return true;
if (!script->hasPollutedGlobalScope()) {
frame.push(ObjectValue(script->global()));
return true;
}
return emit_JSOP_BINDNAME();
}
bool

View File

@ -6202,7 +6202,7 @@ DoBindNameFallback(JSContext *cx, BaselineFrame *frame, ICBindName_Fallback *stu
mozilla::DebugOnly<JSOp> op = JSOp(*pc);
FallbackICSpew(cx, stub, "BindName(%s)", js_CodeName[JSOp(*pc)]);
MOZ_ASSERT(op == JSOP_BINDNAME);
MOZ_ASSERT(op == JSOP_BINDNAME || op == JSOP_BINDGNAME);
RootedPropertyName name(cx, frame->script()->getName(pc));

View File

@ -1821,9 +1821,6 @@ IonBuilder::inspectOpcode(JSOp op)
return jsop_getgname(name);
}
case JSOP_BINDGNAME:
return pushConstant(ObjectValue(script()->global()));
case JSOP_SETGNAME:
case JSOP_STRICTSETGNAME:
{
@ -1844,6 +1841,10 @@ IonBuilder::inspectOpcode(JSOp op)
return jsop_intrinsic(name);
}
case JSOP_BINDGNAME:
if (!script()->hasPollutedGlobalScope())
return pushConstant(ObjectValue(script()->global()));
// Fall through to JSOP_BINDNAME
case JSOP_BINDNAME:
return jsop_bindname(info().getName(pc));

View File

@ -2038,28 +2038,33 @@ CASE(JSOP_SETCONST)
}
END_CASE(JSOP_SETCONST)
CASE(JSOP_BINDGNAME)
PUSH_OBJECT(REGS.fp()->global());
END_CASE(JSOP_BINDGNAME)
CASE(JSOP_BINDINTRINSIC)
PUSH_OBJECT(*cx->global()->intrinsicsHolder());
END_CASE(JSOP_BINDINTRINSIC)
CASE(JSOP_BINDGNAME)
CASE(JSOP_BINDNAME)
{
RootedObject &scopeChain = rootObject0;
scopeChain = REGS.fp()->scopeChain();
JSOp op = JSOp(*REGS.pc);
if (op == JSOP_BINDNAME || script->hasPollutedGlobalScope()) {
RootedObject &scopeChain = rootObject0;
scopeChain = REGS.fp()->scopeChain();
RootedPropertyName &name = rootName0;
name = script->getName(REGS.pc);
RootedPropertyName &name = rootName0;
name = script->getName(REGS.pc);
/* Assigning to an undeclared name adds a property to the global object. */
RootedObject &scope = rootObject1;
if (!LookupNameUnqualified(cx, name, scopeChain, &scope))
goto error;
/* Assigning to an undeclared name adds a property to the global object. */
RootedObject &scope = rootObject1;
if (!LookupNameUnqualified(cx, name, scopeChain, &scope))
goto error;
PUSH_OBJECT(*scope);
PUSH_OBJECT(*scope);
} else {
PUSH_OBJECT(REGS.fp()->global());
}
static_assert(JSOP_BINDNAME_LENGTH == JSOP_BINDGNAME_LENGTH,
"We're sharing the END_CASE so the lengths better match");
}
END_CASE(JSOP_BINDNAME)
@ -2721,6 +2726,8 @@ CASE(JSOP_GIMPLICITTHIS)
// Treat it like JSOP_UNDEFINED.
PUSH_UNDEFINED();
}
static_assert(JSOP_IMPLICITTHIS_LENGTH == JSOP_GIMPLICITTHIS_LENGTH,
"We're sharing the END_CASE so the lengths better match");
}
END_CASE(JSOP_IMPLICITTHIS)

View File

@ -1769,9 +1769,10 @@
macro(JSOP_UNUSED212, 212, "unused212", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED213, 213, "unused213", NULL, 1, 0, 0, JOF_BYTE) \
/*
* Pushes the global scope onto the stack.
* Pushes the global scope onto the stack if the script doesn't have a
* polluted global scope. Otherwise will act like JSOP_BINDNAME.
*
* 'nameIndex' is not used.
* 'nameIndex' is only used when acting like JSOP_BINDNAME.
* Category: Variables and Scopes
* Type: Free Variables
* Operands: uint32_t nameIndex