зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1234191 - Ensure JSOP_CHECKRETURN consults the correct scope object. (r=shu, r=jandem)
This commit is contained in:
Родитель
db9ef16cf1
Коммит
ace68b649e
|
@ -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");
|
Загрузка…
Ссылка в новой задаче