Bug 1175394 part 2 - Rename normal/strict arguments to mapped/unmapped arguments. r=jorendorff

This commit is contained in:
Jan de Mooij 2015-09-02 13:05:30 +02:00
parent 8be1e90dc5
commit 7c28c879fe
9 changed files with 143 additions and 131 deletions

View File

@ -132,8 +132,8 @@ namespace JS {
_(ICGetElemStub_Dense) \
_(ICGetElemStub_DenseHole) \
_(ICGetElemStub_TypedArray) \
_(ICGetElemStub_ArgsElement) \
_(ICGetElemStub_ArgsElementStrict) \
_(ICGetElemStub_ArgsElementMapped) \
_(ICGetElemStub_ArgsElementUnmapped) \
\
_(ICSetElemStub_Dense) \
_(ICSetElemStub_TypedArray) \

View File

@ -2838,9 +2838,9 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_
// Check for ArgumentsObj[int] accesses
if (obj->is<ArgumentsObject>() && rhs.isInt32()) {
ICGetElem_Arguments::Which which = ICGetElem_Arguments::Normal;
if (obj->is<StrictArgumentsObject>())
which = ICGetElem_Arguments::Strict;
ICGetElem_Arguments::Which which = ICGetElem_Arguments::Mapped;
if (obj->is<UnmappedArgumentsObject>())
which = ICGetElem_Arguments::Unmapped;
if (!ArgumentsGetElemStubExists(stub, which)) {
JitSpew(JitSpew_BaselineIC, " Generating GetElem(ArgsObj[Int32]) stub");
ICGetElem_Arguments::Compiler compiler(
@ -3829,11 +3829,12 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
MOZ_ASSERT(which_ == ICGetElem_Arguments::Strict ||
which_ == ICGetElem_Arguments::Normal);
MOZ_ASSERT(which_ == ICGetElem_Arguments::Mapped ||
which_ == ICGetElem_Arguments::Unmapped);
bool isStrict = which_ == ICGetElem_Arguments::Strict;
const Class* clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
const Class* clasp = (which_ == ICGetElem_Arguments::Mapped)
? &MappedArgumentsObject::class_
: &UnmappedArgumentsObject::class_;
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
Register scratchReg = regs.takeAny();
@ -5947,10 +5948,10 @@ TryAttachLengthStub(JSContext* cx, JSScript* script, ICGetProp_Fallback* stub, H
if (obj->is<ArgumentsObject>() && res.isInt32()) {
JitSpew(JitSpew_BaselineIC, " Generating GetProp(ArgsObj.length %s) stub",
obj->is<StrictArgumentsObject>() ? "Strict" : "Normal");
ICGetProp_ArgumentsLength::Which which = ICGetProp_ArgumentsLength::Normal;
if (obj->is<StrictArgumentsObject>())
which = ICGetProp_ArgumentsLength::Strict;
obj->is<MappedArgumentsObject>() ? "Mapped" : "Unmapped");
ICGetProp_ArgumentsLength::Which which = ICGetProp_ArgumentsLength::Mapped;
if (obj->is<UnmappedArgumentsObject>())
which = ICGetProp_ArgumentsLength::Unmapped;
ICGetProp_ArgumentsLength::Compiler compiler(cx, which);
ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
if (!newStub)
@ -7417,11 +7418,12 @@ ICGetProp_ArgumentsLength::Compiler::generateStubCode(MacroAssembler& masm)
EmitStubGuardFailure(masm);
return true;
}
MOZ_ASSERT(which_ == ICGetProp_ArgumentsLength::Strict ||
which_ == ICGetProp_ArgumentsLength::Normal);
MOZ_ASSERT(which_ == ICGetProp_ArgumentsLength::Mapped ||
which_ == ICGetProp_ArgumentsLength::Unmapped);
bool isStrict = which_ == ICGetProp_ArgumentsLength::Strict;
const Class* clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
const Class* clasp = (which_ == ICGetProp_ArgumentsLength::Mapped)
? &MappedArgumentsObject::class_
: &UnmappedArgumentsObject::class_;
Register scratchReg = R1.scratchReg();

View File

@ -1768,7 +1768,7 @@ class ICGetElem_Arguments : public ICMonitoredStub
{
friend class ICStubSpace;
public:
enum Which { Normal, Strict, Magic };
enum Which { Mapped, Unmapped, Magic };
private:
ICGetElem_Arguments(JitCode* stubCode, ICStub* firstMonitorStub, Which which)
@ -3519,7 +3519,7 @@ class ICGetProp_ArgumentsLength : public ICStub
{
friend class ICStubSpace;
public:
enum Which { Normal, Strict, Magic };
enum Which { Mapped, Unmapped, Magic };
protected:
explicit ICGetProp_ArgumentsLength(JitCode* stubCode)

View File

@ -1858,7 +1858,7 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext* cx, HandleScript outerScript,
if (!(outputType == MIRType_Value || outputType == MIRType_Int32))
return true;
if (hasArgumentsLengthStub(obj->is<StrictArgumentsObject>()))
if (hasArgumentsLengthStub(obj->is<MappedArgumentsObject>()))
return true;
*emitted = true;
@ -1878,10 +1878,7 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext* cx, HandleScript outerScript,
}
MOZ_ASSERT(object() != tmpReg);
const Class* clasp = obj->is<StrictArgumentsObject>() ? &StrictArgumentsObject::class_
: &NormalArgumentsObject::class_;
masm.branchTestObjClass(Assembler::NotEqual, object(), tmpReg, clasp, &failures);
masm.branchTestObjClass(Assembler::NotEqual, object(), tmpReg, obj->getClass(), &failures);
// Get initial ArgsObj length value, test if length has been overridden.
masm.unboxInt32(Address(object(), ArgumentsObject::getInitialLengthSlotOffset()), tmpReg);
@ -1901,16 +1898,16 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext* cx, HandleScript outerScript,
masm.bind(&failures);
attacher.jumpNextStub(masm);
if (obj->is<StrictArgumentsObject>()) {
MOZ_ASSERT(!hasStrictArgumentsLengthStub_);
hasStrictArgumentsLengthStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj length (strict)",
if (obj->is<UnmappedArgumentsObject>()) {
MOZ_ASSERT(!hasUnmappedArgumentsLengthStub_);
hasUnmappedArgumentsLengthStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj length (unmapped)",
JS::TrackedOutcome::ICGetPropStub_ArgumentsLength);
}
MOZ_ASSERT(!hasNormalArgumentsLengthStub_);
hasNormalArgumentsLengthStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj length (normal)",
MOZ_ASSERT(!hasMappedArgumentsLengthStub_);
hasMappedArgumentsLengthStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj length (mapped)",
JS::TrackedOutcome::ICGetPropStub_ArgumentsLength);
}
@ -2028,8 +2025,8 @@ GetPropertyIC::reset(ReprotectCode reprotect)
IonCache::reset(reprotect);
hasTypedArrayLengthStub_ = false;
hasSharedTypedArrayLengthStub_ = false;
hasStrictArgumentsLengthStub_ = false;
hasNormalArgumentsLengthStub_ = false;
hasMappedArgumentsLengthStub_ = false;
hasUnmappedArgumentsLengthStub_ = false;
hasGenericProxyStub_ = false;
}
@ -3931,10 +3928,7 @@ GetElementIC::attachArgumentsElement(JSContext* cx, HandleScript outerScript, Io
Register tmpReg = output().scratchReg().gpr();
MOZ_ASSERT(tmpReg != InvalidReg);
const Class* clasp = obj->is<StrictArgumentsObject>() ? &StrictArgumentsObject::class_
: &NormalArgumentsObject::class_;
masm.branchTestObjClass(Assembler::NotEqual, object(), tmpReg, clasp, &failures);
masm.branchTestObjClass(Assembler::NotEqual, object(), tmpReg, obj->getClass(), &failures);
// Get initial ArgsObj length value, test if length has been overridden.
masm.unboxInt32(Address(object(), ArgumentsObject::getInitialLengthSlotOffset()), tmpReg);
@ -4016,18 +4010,17 @@ GetElementIC::attachArgumentsElement(JSContext* cx, HandleScript outerScript, Io
masm.bind(&failures);
attacher.jumpNextStub(masm);
if (obj->is<StrictArgumentsObject>()) {
MOZ_ASSERT(!hasStrictArgumentsStub_);
hasStrictArgumentsStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj element (strict)",
JS::TrackedOutcome::ICGetElemStub_ArgsElementStrict);
if (obj->is<UnmappedArgumentsObject>()) {
MOZ_ASSERT(!hasUnmappedArgumentsStub_);
hasUnmappedArgumentsStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj element (unmapped)",
JS::TrackedOutcome::ICGetElemStub_ArgsElementUnmapped);
}
MOZ_ASSERT(!hasNormalArgumentsStub_);
hasNormalArgumentsStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj element (normal)",
JS::TrackedOutcome::ICGetElemStub_ArgsElement);
MOZ_ASSERT(!hasMappedArgumentsStub_);
hasMappedArgumentsStub_ = true;
return linkAndAttachStub(cx, masm, attacher, ion, "ArgsObj element (mapped)",
JS::TrackedOutcome::ICGetElemStub_ArgsElementMapped);
}
bool
@ -4058,7 +4051,7 @@ GetElementIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex,
bool attachedStub = false;
if (cache.canAttachStub()) {
if (IsOptimizableArgumentsObjectForGetElem(obj, idval) &&
!cache.hasArgumentsStub(obj->is<StrictArgumentsObject>()) &&
!cache.hasArgumentsStub(obj->is<MappedArgumentsObject>()) &&
(cache.index().hasValue() ||
cache.index().type() == MIRType_Int32) &&
(cache.output().hasValue() || !cache.output().typedReg().isFloat()))
@ -4116,8 +4109,8 @@ GetElementIC::reset(ReprotectCode reprotect)
{
IonCache::reset(reprotect);
hasDenseStub_ = false;
hasStrictArgumentsStub_ = false;
hasNormalArgumentsStub_ = false;
hasMappedArgumentsStub_ = false;
hasUnmappedArgumentsStub_ = false;
}
static bool

View File

@ -392,8 +392,8 @@ class GetPropertyIC : public IonCache
bool monitoredResult_ : 1;
bool hasTypedArrayLengthStub_ : 1;
bool hasSharedTypedArrayLengthStub_ : 1;
bool hasStrictArgumentsLengthStub_ : 1;
bool hasNormalArgumentsLengthStub_ : 1;
bool hasMappedArgumentsLengthStub_ : 1;
bool hasUnmappedArgumentsLengthStub_ : 1;
bool hasGenericProxyStub_ : 1;
public:
@ -410,8 +410,8 @@ class GetPropertyIC : public IonCache
monitoredResult_(monitoredResult),
hasTypedArrayLengthStub_(false),
hasSharedTypedArrayLengthStub_(false),
hasStrictArgumentsLengthStub_(false),
hasNormalArgumentsLengthStub_(false),
hasMappedArgumentsLengthStub_(false),
hasUnmappedArgumentsLengthStub_(false),
hasGenericProxyStub_(false)
{
}
@ -435,8 +435,8 @@ class GetPropertyIC : public IonCache
bool hasAnyTypedArrayLengthStub(HandleObject obj) const {
return obj->is<TypedArrayObject>() ? hasTypedArrayLengthStub_ : hasSharedTypedArrayLengthStub_;
}
bool hasArgumentsLengthStub(bool strict) const {
return strict ? hasStrictArgumentsLengthStub_ : hasNormalArgumentsLengthStub_;
bool hasArgumentsLengthStub(bool mapped) const {
return mapped ? hasMappedArgumentsLengthStub_ : hasUnmappedArgumentsLengthStub_;
}
bool hasGenericProxyStub() const {
return hasGenericProxyStub_;
@ -622,8 +622,8 @@ class GetElementIC : public IonCache
bool monitoredResult_ : 1;
bool allowDoubleResult_ : 1;
bool hasDenseStub_ : 1;
bool hasStrictArgumentsStub_ : 1;
bool hasNormalArgumentsStub_ : 1;
bool hasMappedArgumentsStub_ : 1;
bool hasUnmappedArgumentsStub_ : 1;
size_t failedUpdates_;
@ -639,8 +639,8 @@ class GetElementIC : public IonCache
monitoredResult_(monitoredResult),
allowDoubleResult_(allowDoubleResult),
hasDenseStub_(false),
hasStrictArgumentsStub_(false),
hasNormalArgumentsStub_(false),
hasMappedArgumentsStub_(false),
hasUnmappedArgumentsStub_(false),
failedUpdates_(0)
{
}
@ -667,8 +667,8 @@ class GetElementIC : public IonCache
bool hasDenseStub() const {
return hasDenseStub_;
}
bool hasArgumentsStub(bool strict) const {
return strict ? hasStrictArgumentsStub_ : hasNormalArgumentsStub_;
bool hasArgumentsStub(bool mapped) const {
return mapped ? hasMappedArgumentsStub_ : hasUnmappedArgumentsStub_;
}
void setHasDenseStub() {
MOZ_ASSERT(!hasDenseStub());

View File

@ -79,8 +79,8 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
scheduledForDestruction(false),
maybeAlive(true),
jitCompartment_(nullptr),
normalArgumentsTemplate_(nullptr),
strictArgumentsTemplate_(nullptr)
mappedArgumentsTemplate_(nullptr),
unmappedArgumentsTemplate_(nullptr)
{
PodArrayZero(sawDeprecatedLanguageExtension);
runtime_->numCompartments++;
@ -715,11 +715,11 @@ JSCompartment::sweepCrossCompartmentWrappers()
void
JSCompartment::sweepTemplateObjects()
{
if (normalArgumentsTemplate_ && IsAboutToBeFinalized(&normalArgumentsTemplate_))
normalArgumentsTemplate_.set(nullptr);
if (mappedArgumentsTemplate_ && IsAboutToBeFinalized(&mappedArgumentsTemplate_))
mappedArgumentsTemplate_.set(nullptr);
if (strictArgumentsTemplate_ && IsAboutToBeFinalized(&strictArgumentsTemplate_))
strictArgumentsTemplate_.set(nullptr);
if (unmappedArgumentsTemplate_ && IsAboutToBeFinalized(&unmappedArgumentsTemplate_))
unmappedArgumentsTemplate_.set(nullptr);
}
/* static */ void

View File

@ -700,8 +700,8 @@ struct JSCompartment
private:
js::jit::JitCompartment* jitCompartment_;
js::ReadBarriered<js::ArgumentsObject*> normalArgumentsTemplate_;
js::ReadBarriered<js::ArgumentsObject*> strictArgumentsTemplate_;
js::ReadBarriered<js::ArgumentsObject*> mappedArgumentsTemplate_;
js::ReadBarriered<js::ArgumentsObject*> unmappedArgumentsTemplate_;
public:
bool ensureJitCompartmentExists(JSContext* cx);
@ -722,7 +722,7 @@ struct JSCompartment
DeprecatedLanguageExtensionCount
};
js::ArgumentsObject* getOrCreateArgumentsTemplateObject(JSContext* cx, bool strict);
js::ArgumentsObject* getOrCreateArgumentsTemplateObject(JSContext* cx, bool mapped);
private:
// Used for collecting telemetry on SpiderMonkey's deprecated language extensions.

View File

@ -158,9 +158,11 @@ struct CopyScriptFrameIterArgs
};
ArgumentsObject*
ArgumentsObject::createTemplateObject(JSContext* cx, bool strict)
ArgumentsObject::createTemplateObject(JSContext* cx, bool mapped)
{
const Class* clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
const Class* clasp = mapped
? &MappedArgumentsObject::class_
: &UnmappedArgumentsObject::class_;
RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
if (!proto)
@ -186,16 +188,16 @@ ArgumentsObject::createTemplateObject(JSContext* cx, bool strict)
}
ArgumentsObject*
JSCompartment::getOrCreateArgumentsTemplateObject(JSContext* cx, bool strict)
JSCompartment::getOrCreateArgumentsTemplateObject(JSContext* cx, bool mapped)
{
ReadBarriered<ArgumentsObject*>& obj =
strict ? strictArgumentsTemplate_ : normalArgumentsTemplate_;
mapped ? mappedArgumentsTemplate_ : unmappedArgumentsTemplate_;
ArgumentsObject* templateObj = obj;
if (templateObj)
return templateObj;
templateObj = ArgumentsObject::createTemplateObject(cx, strict);
templateObj = ArgumentsObject::createTemplateObject(cx, mapped);
if (!templateObj)
return nullptr;
@ -207,8 +209,8 @@ template <typename CopyArgs>
/* static */ ArgumentsObject*
ArgumentsObject::create(JSContext* cx, HandleFunction callee, unsigned numActuals, CopyArgs& copy)
{
bool strict = !callee->nonLazyScript()->hasMappedArgsObj(); // TODO: rename "strict" everywhere?
ArgumentsObject* templateObj = cx->compartment()->getOrCreateArgumentsTemplateObject(cx, strict);
bool mapped = callee->nonLazyScript()->hasMappedArgsObj();
ArgumentsObject* templateObj = cx->compartment()->getOrCreateArgumentsTemplateObject(cx, mapped);
if (!templateObj)
return nullptr;
@ -313,8 +315,9 @@ ArgumentsObject::createForIon(JSContext* cx, jit::JitFrameLayout* frame, HandleO
return create(cx, callee, frame->numActualArgs(), copy);
}
static bool
args_delProperty(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& result)
/* static */ bool
ArgumentsObject::obj_delProperty(JSContext* cx, HandleObject obj, HandleId id,
ObjectOpResult& result)
{
ArgumentsObject& argsobj = obj->as<ArgumentsObject>();
if (JSID_IS_INT(id)) {
@ -324,15 +327,15 @@ args_delProperty(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& r
} else if (JSID_IS_ATOM(id, cx->names().length)) {
argsobj.markLengthOverridden();
} else if (JSID_IS_ATOM(id, cx->names().callee)) {
argsobj.as<NormalArgumentsObject>().clearCallee();
argsobj.as<MappedArgumentsObject>().clearCallee();
}
return result.succeed();
}
static bool
ArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
MappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
NormalArgumentsObject& argsobj = obj->as<NormalArgumentsObject>();
MappedArgumentsObject& argsobj = obj->as<MappedArgumentsObject>();
if (JSID_IS_INT(id)) {
/*
* arg can exceed the number of arguments if a script changed the
@ -353,12 +356,12 @@ ArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
}
static bool
ArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
ObjectOpResult& result)
MappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
ObjectOpResult& result)
{
if (!obj->is<NormalArgumentsObject>())
if (!obj->is<MappedArgumentsObject>())
return result.succeed();
Handle<NormalArgumentsObject*> argsobj = obj.as<NormalArgumentsObject>();
Handle<MappedArgumentsObject*> argsobj = obj.as<MappedArgumentsObject>();
Rooted<PropertyDescriptor> desc(cx);
if (!GetOwnPropertyDescriptor(cx, argsobj, id, &desc))
@ -384,20 +387,21 @@ ArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
/*
* For simplicity we use delete/define to replace the property with a
* simple data property. Note that we rely on args_delProperty to clear the
* corresponding reserved slot so the GC can collect its value. Note also
* that we must define the property instead of setting it in case the user
* has changed the prototype to an object that has a setter for this id.
* simple data property. Note that we rely on ArgumentsObject::obj_delProperty
* to clear the corresponding reserved slot so the GC can collect its value.
* Note also that we must define the property instead of setting it in case
* the user has changed the prototype to an object that has a setter for
* this id.
*/
ObjectOpResult ignored;
return NativeDeleteProperty(cx, argsobj, id, ignored) &&
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs, result);
}
static bool
args_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
/* static */ bool
MappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
{
Rooted<NormalArgumentsObject*> argsobj(cx, &obj->as<NormalArgumentsObject>());
Rooted<MappedArgumentsObject*> argsobj(cx, &obj->as<MappedArgumentsObject>());
unsigned attrs = JSPROP_SHARED | JSPROP_SHADOWABLE | JSPROP_RESOLVING;
if (JSID_IS_INT(id)) {
@ -417,17 +421,20 @@ args_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
return true;
}
if (!NativeDefineProperty(cx, argsobj, id, UndefinedHandleValue, ArgGetter, ArgSetter, attrs))
if (!NativeDefineProperty(cx, argsobj, id, UndefinedHandleValue,
MappedArgGetter, MappedArgSetter, attrs))
{
return false;
}
*resolvedp = true;
return true;
}
static bool
args_enumerate(JSContext* cx, HandleObject obj)
/* static */ bool
MappedArgumentsObject::obj_enumerate(JSContext* cx, HandleObject obj)
{
Rooted<NormalArgumentsObject*> argsobj(cx, &obj->as<NormalArgumentsObject>());
Rooted<MappedArgumentsObject*> argsobj(cx, &obj->as<MappedArgumentsObject>());
RootedId id(cx);
bool found;
@ -451,9 +458,9 @@ args_enumerate(JSContext* cx, HandleObject obj)
}
static bool
StrictArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
UnmappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
StrictArgumentsObject& argsobj = obj->as<StrictArgumentsObject>();
UnmappedArgumentsObject& argsobj = obj->as<UnmappedArgumentsObject>();
if (JSID_IS_INT(id)) {
/*
@ -472,12 +479,12 @@ StrictArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
}
static bool
StrictArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
ObjectOpResult& result)
UnmappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
ObjectOpResult& result)
{
if (!obj->is<StrictArgumentsObject>())
if (!obj->is<UnmappedArgumentsObject>())
return result.succeed();
Handle<StrictArgumentsObject*> argsobj = obj.as<StrictArgumentsObject>();
Handle<UnmappedArgumentsObject*> argsobj = obj.as<UnmappedArgumentsObject>();
Rooted<PropertyDescriptor> desc(cx);
if (!GetOwnPropertyDescriptor(cx, argsobj, id, &desc))
@ -499,22 +506,22 @@ StrictArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
/*
* For simplicity we use delete/define to replace the property with a
* simple data property. Note that we rely on args_delProperty to clear the
* corresponding reserved slot so the GC can collect its value.
* simple data property. Note that we rely on ArgumentsObject::obj_delProperty
* to clear the corresponding reserved slot so the GC can collect its value.
*/
ObjectOpResult ignored;
return NativeDeleteProperty(cx, argsobj, id, ignored) &&
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs, result);
}
static bool
strictargs_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
/* static */ bool
UnmappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
{
Rooted<StrictArgumentsObject*> argsobj(cx, &obj->as<StrictArgumentsObject>());
Rooted<UnmappedArgumentsObject*> argsobj(cx, &obj->as<UnmappedArgumentsObject>());
unsigned attrs = JSPROP_SHARED | JSPROP_SHADOWABLE;
GetterOp getter = StrictArgGetter;
SetterOp setter = StrictArgSetter;
GetterOp getter = UnmappedArgGetter;
SetterOp setter = UnmappedArgSetter;
if (JSID_IS_INT(id)) {
uint32_t arg = uint32_t(JSID_TO_INT(id));
@ -542,10 +549,10 @@ strictargs_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp
return true;
}
static bool
strictargs_enumerate(JSContext* cx, HandleObject obj)
/* static */ bool
UnmappedArgumentsObject::obj_enumerate(JSContext* cx, HandleObject obj)
{
Rooted<StrictArgumentsObject*> argsobj(cx, &obj->as<StrictArgumentsObject>());
Rooted<UnmappedArgumentsObject*> argsobj(cx, &obj->as<UnmappedArgumentsObject>());
RootedId id(cx);
bool found;
@ -624,19 +631,19 @@ ArgumentsObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject
* stack frame with their corresponding property values in the frame's
* arguments object.
*/
const Class NormalArgumentsObject::class_ = {
const Class MappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_CALLBACK |
JSCLASS_HAS_RESERVED_SLOTS(NormalArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_RESERVED_SLOTS(MappedArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
nullptr, /* addProperty */
args_delProperty,
ArgumentsObject::obj_delProperty,
nullptr, /* getProperty */
nullptr, /* setProperty */
args_enumerate,
args_resolve,
MappedArgumentsObject::obj_enumerate,
MappedArgumentsObject::obj_resolve,
nullptr, /* mayResolve */
nullptr, /* convert */
ArgumentsObject::finalize,
@ -647,23 +654,22 @@ const Class NormalArgumentsObject::class_ = {
};
/*
* Strict mode arguments is significantly less magical than non-strict mode
* arguments, so it is represented by a different class while sharing some
* functionality.
* Unmapped arguments is significantly less magical than mapped arguments, so
* it is represented by a different class while sharing some functionality.
*/
const Class StrictArgumentsObject::class_ = {
const Class UnmappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_CALLBACK |
JSCLASS_HAS_RESERVED_SLOTS(StrictArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_RESERVED_SLOTS(UnmappedArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
nullptr, /* addProperty */
args_delProperty,
ArgumentsObject::obj_delProperty,
nullptr, /* getProperty */
nullptr, /* setProperty */
strictargs_enumerate,
strictargs_resolve,
UnmappedArgumentsObject::obj_enumerate,
UnmappedArgumentsObject::obj_resolve,
nullptr, /* mayResolve */
nullptr, /* convert */
ArgumentsObject::finalize,

View File

@ -136,6 +136,9 @@ class ArgumentsObject : public NativeObject
return reinterpret_cast<ArgumentsData*>(getFixedSlot(DATA_SLOT).toPrivate());
}
static bool obj_delProperty(JSContext* cx, HandleObject obj, HandleId id,
ObjectOpResult& result);
public:
static const uint32_t RESERVED_SLOTS = 3;
static const gc::AllocKind FINALIZE_KIND = gc::AllocKind::OBJECT4_BACKGROUND;
@ -154,7 +157,7 @@ class ArgumentsObject : public NativeObject
static ArgumentsObject* createForIon(JSContext* cx, jit::JitFrameLayout* frame,
HandleObject scopeChain);
static ArgumentsObject* createTemplateObject(JSContext* cx, bool strict);
static ArgumentsObject* createTemplateObject(JSContext* cx, bool mapped);
/*
* Return the initial length of the arguments. This may differ from the
@ -310,7 +313,7 @@ class ArgumentsObject : public NativeObject
ArgumentsObject* obj, ArgumentsData* data);
};
class NormalArgumentsObject : public ArgumentsObject
class MappedArgumentsObject : public ArgumentsObject
{
public:
static const Class class_;
@ -327,12 +330,20 @@ class NormalArgumentsObject : public ArgumentsObject
void clearCallee() {
data()->callee = MagicValue(JS_OVERWRITTEN_CALLEE);
}
private:
static bool obj_enumerate(JSContext* cx, HandleObject obj);
static bool obj_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp);
};
class StrictArgumentsObject : public ArgumentsObject
class UnmappedArgumentsObject : public ArgumentsObject
{
public:
static const Class class_;
private:
static bool obj_enumerate(JSContext* cx, HandleObject obj);
static bool obj_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp);
};
} // namespace js
@ -341,7 +352,7 @@ template<>
inline bool
JSObject::is<js::ArgumentsObject>() const
{
return is<js::NormalArgumentsObject>() || is<js::StrictArgumentsObject>();
return is<js::MappedArgumentsObject>() || is<js::UnmappedArgumentsObject>();
}
#endif /* vm_ArgumentsObject_h */