mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-18 06:45:33 +00:00
Bug 1175394 part 2 - Rename normal/strict arguments to mapped/unmapped arguments. r=jorendorff
This commit is contained in:
parent
8be1e90dc5
commit
7c28c879fe
@ -132,8 +132,8 @@ namespace JS {
|
||||
_(ICGetElemStub_Dense) \
|
||||
_(ICGetElemStub_DenseHole) \
|
||||
_(ICGetElemStub_TypedArray) \
|
||||
_(ICGetElemStub_ArgsElement) \
|
||||
_(ICGetElemStub_ArgsElementStrict) \
|
||||
_(ICGetElemStub_ArgsElementMapped) \
|
||||
_(ICGetElemStub_ArgsElementUnmapped) \
|
||||
\
|
||||
_(ICSetElemStub_Dense) \
|
||||
_(ICSetElemStub_TypedArray) \
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user