зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 559f43c43369 (bug 1341061)
This commit is contained in:
Родитель
1642f69ece
Коммит
12475239db
|
@ -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, ®S.sp[-1].toObject());
|
||||
ReservedRooted<JSObject*> obj(&rootObject0, ®S.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 */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче