Bug 1165794 - Correctly handle getter/setters like methods everywhere. r=efaust

This commit is contained in:
Tom Schuster 2015-05-19 18:21:11 +02:00
parent dc759e14b2
commit 16ff100dbd
9 changed files with 60 additions and 8 deletions

View File

@ -283,9 +283,8 @@ frontend::CompileScript(ExclusiveContext* cx, LifoAlloc* alloc, HandleObject sco
return nullptr;
bool savedCallerFun = evalCaller && evalCaller->functionOrCallerFunction();
bool allowSuperProperty = savedCallerFun && (evalCaller->functionOrCallerFunction()->isMethod() ||
evalCaller->functionOrCallerFunction()->isGetter() ||
evalCaller->functionOrCallerFunction()->isSetter());
bool allowSuperProperty = savedCallerFun &&
evalCaller->functionOrCallerFunction()->allowSuperProperty();
Directives directives(options.strictOption);
GlobalSharedContext globalsc(cx, directives, options.extraWarningsOption, allowSuperProperty);

View File

@ -6766,7 +6766,7 @@ BytecodeEmitter::emitPropertyList(ParseNode* pn, MutableHandlePlainObject objp,
if (propdef->pn_right->isKind(PNK_FUNCTION) &&
propdef->pn_right->pn_funbox->needsHomeObject())
{
MOZ_ASSERT(propdef->pn_right->pn_funbox->function()->isMethod());
MOZ_ASSERT(propdef->pn_right->pn_funbox->function()->allowSuperProperty());
if (!emit2(JSOP_INITHOMEOBJECT, isIndex))
return false;
}

View File

@ -1235,9 +1235,11 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind, Hand
break;
case Getter:
flags = JSFunction::INTERPRETED_GETTER;
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
break;
case Setter:
flags = JSFunction::INTERPRETED_SETTER;
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
break;
default:
flags = JSFunction::INTERPRETED_NORMAL;

View File

@ -339,7 +339,7 @@ class FunctionBox : public ObjectBox, public SharedContext
}
bool allowSuperProperty() const {
return function()->isMethod() || function()->isGetter() || function()->isSetter();
return function()->allowSuperProperty();
}
};

View File

@ -0,0 +1,4 @@
var o = {get a() {
return eval("5");
}}
assertEq(o.a, 5);

View File

@ -1713,7 +1713,7 @@ CodeGenerator::visitLambda(LLambda* lir)
emitLambdaInit(output, scopeChain, info);
if (info.flags & JSFunction::EXTENDED) {
MOZ_ASSERT(info.fun->isMethod());
MOZ_ASSERT(info.fun->allowSuperProperty());
static_assert(FunctionExtended::NUM_EXTENDED_SLOTS == 2, "All slots must be initialized");
masm.storeValue(UndefinedValue(), Address(output, FunctionExtended::offsetOfExtendedSlot(0)));
masm.storeValue(UndefinedValue(), Address(output, FunctionExtended::offsetOfExtendedSlot(1)));

View File

@ -174,6 +174,10 @@ class JSFunction : public js::NativeObject
return kind() == Method && isConstructor();
}
bool allowSuperProperty() const {
return isMethod() || isGetter() || isSetter();
}
bool hasResolvedLength() const { return flags() & RESOLVED_LENGTH; }
bool hasResolvedName() const { return flags() & RESOLVED_NAME; }

View File

@ -0,0 +1,43 @@
var test = `
class base {
constructor() {}
getValue() {
return this._prop;
}
setValue(v) {
this._prop = v;
}
}
class derived extends base {
constructor() {}
get a() { return super.getValue(); }
set a(v) { super.setValue(v); }
get b() { return eval('super.getValue()'); }
set b(v) { eval('super.setValue(v);'); }
test() {
this.a = 15;
assertEq(this.a, 15);
assertEq(this.b, 15);
this.b = 30;
assertEq(this.b, 30);
}
}
var derivedInstance = new derived();
derivedInstance.test();
`;
if (classesEnabled())
eval(test);
if (typeof reportCompare === 'function')
reportCompare(0,0,"OK");

View File

@ -3964,7 +3964,7 @@ CASE(JSOP_INITHOMEOBJECT)
/* Load the function to be initialized */
RootedFunction& func = rootFunction0;
func = &REGS.sp[-1].toObject().as<JSFunction>();
MOZ_ASSERT(func->isMethod());
MOZ_ASSERT(func->allowSuperProperty());
/* Load the home object */
RootedNativeObject& obj = rootNativeObject0;
@ -3981,7 +3981,7 @@ CASE(JSOP_SUPERBASE)
for (; !si.done(); ++si) {
if (si.hasScopeObject() && si.type() == ScopeIter::Call) {
JSFunction& callee = si.scope().as<CallObject>().callee();
MOZ_ASSERT(callee.isMethod());
MOZ_ASSERT(callee.allowSuperProperty());
MOZ_ASSERT(callee.nonLazyScript()->needsHomeObject());
const Value& homeObjVal = callee.getExtendedSlot(FunctionExtended::METHOD_HOMEOBJECT_SLOT);