Backed out changeset 559f43c43369 (bug 1341061)

This commit is contained in:
Sebastian Hengst 2017-02-24 23:10:16 +01:00
Родитель 1642f69ece
Коммит 12475239db
8 изменённых файлов: 38 добавлений и 66 удалений

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

@ -4072,29 +4072,6 @@ BytecodeEmitter::emitPropIncDec(ParseNode* pn)
return true;
}
bool
BytecodeEmitter::emitGetNameAtLocationForCompoundAssignment(JSAtom* name, const NameLocation& loc)
{
if (loc.kind() == NameLocation::Kind::Dynamic) {
// For dynamic accesses we need to emit GETBOUNDNAME instead of
// GETNAME for correctness: looking up @@unscopables on the
// environment chain (due to 'with' environments) must only happen
// once.
//
// GETBOUNDNAME uses the environment already pushed on the stack from
// the earlier BINDNAME.
if (!emit1(JSOP_DUP)) // ENV ENV
return false;
if (!emitAtomOp(name, JSOP_GETBOUNDNAME)) // ENV V
return false;
} else {
if (!emitGetNameAtLocation(name, loc)) // ENV? V
return false;
}
return true;
}
bool
BytecodeEmitter::emitNameIncDec(ParseNode* pn)
{
@ -4107,21 +4084,21 @@ BytecodeEmitter::emitNameIncDec(ParseNode* pn)
bool emittedBindOp)
{
JSAtom* name = pn->pn_kid->name();
if (!bce->emitGetNameAtLocationForCompoundAssignment(name, loc)) // ENV? V
if (!bce->emitGetNameAtLocation(name, loc, false)) // SCOPE? V
return false;
if (!bce->emit1(JSOP_POS)) // ENV? N
if (!bce->emit1(JSOP_POS)) // SCOPE? N
return false;
if (post && !bce->emit1(JSOP_DUP)) // ENV? N? N
if (post && !bce->emit1(JSOP_DUP)) // SCOPE? N? N
return false;
if (!bce->emit1(JSOP_ONE)) // ENV? N? N 1
if (!bce->emit1(JSOP_ONE)) // SCOPE? N? N 1
return false;
if (!bce->emit1(binop)) // ENV? N? N+1
if (!bce->emit1(binop)) // SCOPE? N? N+1
return false;
if (post && emittedBindOp) {
if (!bce->emit2(JSOP_PICK, 2)) // N? N+1 ENV?
if (!bce->emit2(JSOP_PICK, 2)) // N? N+1 SCOPE?
return false;
if (!bce->emit1(JSOP_SWAP)) // N? ENV? N+1
if (!bce->emit1(JSOP_SWAP)) // N? SCOPE? N+1
return false;
}
@ -5917,8 +5894,19 @@ BytecodeEmitter::emitAssignment(ParseNode* lhs, JSOp op, ParseNode* rhs)
// For compound assignments, first get the LHS value, then emit
// the RHS and the op.
if (op != JSOP_NOP) {
if (!bce->emitGetNameAtLocationForCompoundAssignment(lhs->name(), lhsLoc))
return false;
if (lhsLoc.kind() == NameLocation::Kind::Dynamic) {
// For dynamic accesses we can do better than a GETNAME
// since the assignment already emitted a BINDNAME on the
// top of the stack. As an optimization, use that to get
// the name.
if (!bce->emit1(JSOP_DUP))
return false;
if (!bce->emitAtomOp(lhs, JSOP_GETBOUNDNAME))
return false;
} else {
if (!bce->emitGetNameAtLocation(lhs->name(), lhsLoc))
return false;
}
}
// Emit the RHS. If we emitted a BIND[G]NAME, then the scope is on

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

@ -545,8 +545,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitGetNameAtLocation(JSAtom* name, const NameLocation& loc,
bool callContext = false);
MOZ_MUST_USE bool emitGetNameAtLocationForCompoundAssignment(JSAtom* name,
const NameLocation& loc);
MOZ_MUST_USE bool emitGetName(JSAtom* name, bool callContext = false) {
return emitGetNameAtLocation(name, lookupName(name), callContext);
}

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

@ -1974,9 +1974,9 @@ ComputeGetPropResult(JSContext* cx, BaselineFrame* frame, JSOp op, HandlePropert
}
} else {
if (op == JSOP_GETBOUNDNAME) {
RootedObject env(cx, &val.toObject());
RootedObject obj(cx, &val.toObject());
RootedId id(cx, NameToId(name));
if (!GetNameBoundInEnvironment(cx, env, id, res))
if (!GetPropertyForNameLookup(cx, obj, id, res))
return false;
} else {
MOZ_ASSERT(op == JSOP_GETPROP || op == JSOP_CALLPROP || op == JSOP_LENGTH);

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

@ -1054,14 +1054,6 @@ IsGlobalLexicalEnvironment(JSObject* env)
env->as<LexicalEnvironmentObject>().isGlobal();
}
inline JSObject*
MaybeUnwrapSyntacticWithEnvironment(JSObject* env)
{
if (env->is<WithEnvironmentObject>() && env->as<WithEnvironmentObject>().isSyntactic())
return &env->as<WithEnvironmentObject>().object();
return env;
}
template <typename SpecificEnvironment>
inline bool
IsFrameInitialEnvironment(AbstractFramePtr frame, SpecificEnvironment& env)

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

@ -174,7 +174,11 @@ GetLengthProperty(const Value& lval, MutableHandleValue vp)
return false;
}
enum class GetNameMode { Normal, TypeOf };
enum class GetNameMode
{
Normal,
TypeOf
};
template <GetNameMode mode>
inline bool
@ -198,7 +202,9 @@ FetchName(JSContext* cx, HandleObject receiver, HandleObject holder, HandlePrope
return false;
} else {
RootedShape shape(cx, prop.shape());
RootedObject normalized(cx, MaybeUnwrapSyntacticWithEnvironment(receiver));
RootedObject normalized(cx, receiver);
if (normalized->is<WithEnvironmentObject>() && !shape->hasDefaultGetter())
normalized = &normalized->as<WithEnvironmentObject>().object();
if (shape->isDataDescriptor() && shape->hasDefaultGetter()) {
/* Fast path for Object instance properties. */
MOZ_ASSERT(shape->hasSlot());

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

@ -2682,10 +2682,10 @@ END_CASE(JSOP_GETPROP_SUPER)
CASE(JSOP_GETBOUNDNAME)
{
ReservedRooted<JSObject*> env(&rootObject0, &REGS.sp[-1].toObject());
ReservedRooted<JSObject*> obj(&rootObject0, &REGS.sp[-1].toObject());
ReservedRooted<jsid> id(&rootId0, NameToId(script->getName(REGS.pc)));
MutableHandleValue rval = REGS.stackHandleAt(-1);
if (!GetNameBoundInEnvironment(cx, env, id, rval))
if (!GetPropertyForNameLookup(cx, obj, id, rval))
goto error;
TypeScript::Monitor(cx, script, REGS.pc, rval);

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

@ -2125,24 +2125,12 @@ js::NativeGetPropertyNoGC(JSContext* cx, NativeObject* obj, const Value& receive
}
bool
js::GetNameBoundInEnvironment(JSContext* cx, HandleObject envArg, HandleId id, MutableHandleValue vp)
js::GetPropertyForNameLookup(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
// Manually unwrap 'with' environments to prevent looking up @@unscopables
// twice.
//
// This is unfortunate because internally, the engine does not distinguish
// HasProperty from HasBinding: both are implemented as a HasPropertyOp
// hook on a WithEnvironmentObject.
//
// In the case of attempting to get the value of a binding already looked
// up via BINDNAME, calling HasProperty on the WithEnvironmentObject is
// equivalent to calling HasBinding a second time. This results in the
// incorrect behavior of performing the @@unscopables check again.
RootedObject env(cx, MaybeUnwrapSyntacticWithEnvironment(envArg));
RootedValue receiver(cx, ObjectValue(*env));
if (env->getOpsGetProperty())
return GeneralizedGetProperty(cx, env, id, receiver, NameLookup, vp);
return NativeGetPropertyInline<CanGC>(cx, env.as<NativeObject>(), receiver, id, NameLookup, vp);
RootedValue receiver(cx, ObjectValue(*obj));
if (obj->getOpsGetProperty())
return GeneralizedGetProperty(cx, obj, id, receiver, NameLookup, vp);
return NativeGetPropertyInline<CanGC>(cx, obj.as<NativeObject>(), receiver, id, NameLookup, vp);
}

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

@ -1393,7 +1393,7 @@ NativeGetExistingProperty(JSContext* cx, HandleObject receiver, HandleNativeObje
/* * */
extern bool
GetNameBoundInEnvironment(JSContext* cx, HandleObject env, HandleId id, MutableHandleValue vp);
GetPropertyForNameLookup(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp);
} /* namespace js */