Bug 1234191 - Ensure JSOP_CHECKRETURN consults the correct scope object. (r=shu, r=jandem)

This commit is contained in:
Eric Faust 2015-12-22 13:52:53 -08:00
Родитель db9ef16cf1
Коммит ace68b649e
3 изменённых файлов: 43 добавлений и 12 удалений

Просмотреть файл

@ -1414,6 +1414,21 @@ BytecodeEmitter::computeHops(ParseNode* pn, BytecodeEmitter** bceOfDefOut)
return hops;
}
uint32_t
BytecodeEmitter::computeHopsToEnclosingFunction()
{
StaticScopeIter<NoGC> ssi(innermostStaticScope());
uint32_t hops = 0;
while (ssi.type() != StaticScopeIter<NoGC>::Function) {
if (ssi.hasSyntacticDynamicScopeObject())
hops++;
ssi++;
}
return hops;
}
bool
BytecodeEmitter::isAliasedName(BytecodeEmitter* bceOfDef, ParseNode* pn)
{
@ -3447,7 +3462,7 @@ BytecodeEmitter::emitCreateFunctionThis()
return false;
BindingIter bi = Bindings::thisBinding(cx, script);
if (!emitStoreToTopScope(bi))
if (!emitStoreToEnclosingFunctionScope(bi))
return false;
if (!emit1(JSOP_POP))
return false;
@ -3556,7 +3571,7 @@ BytecodeEmitter::emitFunctionScript(ParseNode* body)
if (!emit1(JSOP_ARGUMENTS))
return false;
BindingIter bi = Bindings::argumentsBinding(cx, script);
if (!emitStoreToTopScope(bi))
if (!emitStoreToEnclosingFunctionScope(bi))
return false;
if (!emit1(JSOP_POP))
return false;
@ -3624,7 +3639,7 @@ BytecodeEmitter::emitFunctionScript(ParseNode* body)
if (sc->isFunctionBox() && sc->asFunctionBox()->isDerivedClassConstructor()) {
BindingIter bi = Bindings::thisBinding(cx, script);
if (!emitLoadFromTopScope(bi))
if (!emitLoadFromEnclosingFunctionScope(bi))
return false;
if (!emit1(JSOP_CHECKRETURN))
return false;
@ -6668,11 +6683,11 @@ BytecodeEmitter::emitThisLiteral(ParseNode* pn)
}
bool
BytecodeEmitter::emitLoadFromTopScope(BindingIter& bi)
BytecodeEmitter::emitLoadFromEnclosingFunctionScope(BindingIter& bi)
{
if (script->bindingIsAliased(bi)) {
ScopeCoordinate sc;
sc.setHops(0);
sc.setHops(computeHopsToEnclosingFunction());
sc.setSlot(0);
MOZ_ALWAYS_TRUE(lookupAliasedNameSlot(bi->name(), &sc));
return emitAliasedVarOp(JSOP_GETALIASEDVAR, sc, DontCheckLexical);
@ -6682,11 +6697,11 @@ BytecodeEmitter::emitLoadFromTopScope(BindingIter& bi)
}
bool
BytecodeEmitter::emitStoreToTopScope(BindingIter& bi)
BytecodeEmitter::emitStoreToEnclosingFunctionScope(BindingIter& bi)
{
if (script->bindingIsAliased(bi)) {
ScopeCoordinate sc;
sc.setHops(0);
sc.setHops(computeHopsToEnclosingFunction());
sc.setSlot(0); // initialize to silence GCC warning
MOZ_ALWAYS_TRUE(lookupAliasedNameSlot(bi->name(), &sc));
return emitAliasedVarOp(JSOP_SETALIASEDVAR, sc, DontCheckLexical);
@ -6745,7 +6760,7 @@ BytecodeEmitter::emitReturn(ParseNode* pn)
// to ensure that the error is thrown while the scope-chain is still intact.
if (isDerivedClassConstructor) {
BindingIter bi = Bindings::thisBinding(cx, script);
if (!emitLoadFromTopScope(bi))
if (!emitLoadFromEnclosingFunctionScope(bi))
return false;
if (!emit1(JSOP_CHECKRETURN))
return false;

Просмотреть файл

@ -435,10 +435,12 @@ struct BytecodeEmitter
bool emitSetThis(ParseNode* pn);
// These functions are used to emit GETLOCAL/GETALIASEDVAR or
// SETLOCAL/SETALIASEDVAR for a particular binding. The CallObject must be
// on top of the scope chain.
bool emitLoadFromTopScope(BindingIter& bi);
bool emitStoreToTopScope(BindingIter& bi);
// SETLOCAL/SETALIASEDVAR for a particular binding on a function's
// CallObject.
bool emitLoadFromEnclosingFunctionScope(BindingIter& bi);
bool emitStoreToEnclosingFunctionScope(BindingIter& bi);
uint32_t computeHopsToEnclosingFunction();
bool emitJump(JSOp op, ptrdiff_t off, ptrdiff_t* jumpOffset = nullptr);
bool emitCall(JSOp op, uint16_t argc, ParseNode* pn = nullptr);

Просмотреть файл

@ -0,0 +1,14 @@
class base {}
class derived extends base {
constructor() {
try {
(function() { p1(eval()) }())
} catch (e) {
return
}
}
}
assertThrowsInstanceOf(()=>new derived(), ReferenceError);
if (typeof reportCompare === 'function')
reportCompare(0,0,"OK");