Bug 1191236 - Remove extract() methods used by operation forwarding on rooting types, r=terrence

--HG--
extra : rebase_source : 932019cdc060285425e70e7df7c278d0bbdfba5b
This commit is contained in:
Jon Coppeard 2015-08-05 02:38:00 -07:00
parent baac342cae
commit 8586708ac6
8 changed files with 122 additions and 290 deletions

View File

@ -76,7 +76,7 @@ class TraceableHashMapOperations
using Range = typename Map::Range;
using Enum = typename Map::Enum;
const Map& map() const { return static_cast<const Outer*>(this)->extract(); }
const Map& map() const { return static_cast<const Outer*>(this)->get(); }
public:
bool initialized() const { return map().initialized(); }
@ -101,7 +101,7 @@ class MutableTraceableHashMapOperations
using Range = typename Map::Range;
using Enum = typename Map::Enum;
Map& map() { return static_cast<Outer*>(this)->extract(); }
Map& map() { return static_cast<Outer*>(this)->get(); }
public:
bool init(uint32_t len = 16) { return map().init(len); }
@ -140,40 +140,18 @@ class MutableTraceableHashMapOperations
template <typename A, typename B, typename C, typename D, typename E, typename F>
class RootedBase<TraceableHashMap<A,B,C,D,E,F>>
: public MutableTraceableHashMapOperations<JS::Rooted<TraceableHashMap<A,B,C,D,E,F>>, A,B,C,D,E,F>
{
using Map = TraceableHashMap<A,B,C,D,E,F>;
friend class TraceableHashMapOperations<JS::Rooted<Map>, A,B,C,D,E,F>;
const Map& extract() const { return *static_cast<const JS::Rooted<Map>*>(this)->address(); }
friend class MutableTraceableHashMapOperations<JS::Rooted<Map>, A,B,C,D,E,F>;
Map& extract() { return *static_cast<JS::Rooted<Map>*>(this)->address(); }
};
{};
template <typename A, typename B, typename C, typename D, typename E, typename F>
class MutableHandleBase<TraceableHashMap<A,B,C,D,E,F>>
: public MutableTraceableHashMapOperations<JS::MutableHandle<TraceableHashMap<A,B,C,D,E,F>>,
A,B,C,D,E,F>
{
using Map = TraceableHashMap<A,B,C,D,E,F>;
friend class TraceableHashMapOperations<JS::MutableHandle<Map>, A,B,C,D,E,F>;
const Map& extract() const {
return *static_cast<const JS::MutableHandle<Map>*>(this)->address();
}
friend class MutableTraceableHashMapOperations<JS::MutableHandle<Map>, A,B,C,D,E,F>;
Map& extract() { return *static_cast<JS::MutableHandle<Map>*>(this)->address(); }
};
{};
template <typename A, typename B, typename C, typename D, typename E, typename F>
class HandleBase<TraceableHashMap<A,B,C,D,E,F>>
: public TraceableHashMapOperations<JS::Handle<TraceableHashMap<A,B,C,D,E,F>>, A,B,C,D,E,F>
{
using Map = TraceableHashMap<A,B,C,D,E,F>;
friend class TraceableHashMapOperations<JS::Handle<Map>, A,B,C,D,E,F>;
const Map& extract() const { return *static_cast<const JS::Handle<Map>*>(this)->address(); }
};
{};
} /* namespace js */

View File

@ -59,7 +59,7 @@ template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typ
class TraceableVectorOperations
{
using Vec = TraceableVector<T, Capacity, AllocPolicy, TraceFunc>;
const Vec& vec() const { return static_cast<const Outer*>(this)->extract(); }
const Vec& vec() const { return static_cast<const Outer*>(this)->get(); }
public:
const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); }
@ -81,8 +81,8 @@ class MutableTraceableVectorOperations
: public TraceableVectorOperations<Outer, T, Capacity, AllocPolicy, TraceFunc>
{
using Vec = TraceableVector<T, Capacity, AllocPolicy, TraceFunc>;
const Vec& vec() const { return static_cast<const Outer*>(this)->extract(); }
Vec& vec() { return static_cast<Outer*>(this)->extract(); }
const Vec& vec() const { return static_cast<const Outer*>(this)->get(); }
Vec& vec() { return static_cast<Outer*>(this)->get(); }
public:
const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); }
@ -144,59 +144,24 @@ class MutableTraceableVectorOperations
template <typename T, size_t N, typename AP, typename TP>
class RootedBase<TraceableVector<T,N,AP,TP>>
: public MutableTraceableVectorOperations<JS::Rooted<TraceableVector<T,N,AP,TP>>, T,N,AP,TP>
{
using Vec = TraceableVector<T,N,AP,TP>;
friend class TraceableVectorOperations<JS::Rooted<Vec>, T,N,AP,TP>;
const Vec& extract() const { return *static_cast<const JS::Rooted<Vec>*>(this)->address(); }
friend class MutableTraceableVectorOperations<JS::Rooted<Vec>, T,N,AP,TP>;
Vec& extract() { return *static_cast<JS::Rooted<Vec>*>(this)->address(); }
};
{};
template <typename T, size_t N, typename AP, typename TP>
class MutableHandleBase<TraceableVector<T,N,AP,TP>>
: public MutableTraceableVectorOperations<JS::MutableHandle<TraceableVector<T,N,AP,TP>>,
T,N,AP,TP>
{
using Vec = TraceableVector<T,N,AP,TP>;
friend class TraceableVectorOperations<JS::MutableHandle<Vec>, T,N,AP,TP>;
const Vec& extract() const {
return *static_cast<const JS::MutableHandle<Vec>*>(this)->address();
}
friend class MutableTraceableVectorOperations<JS::MutableHandle<Vec>, T,N,AP,TP>;
Vec& extract() { return *static_cast<JS::MutableHandle<Vec>*>(this)->address(); }
};
{};
template <typename T, size_t N, typename AP, typename TP>
class HandleBase<TraceableVector<T,N,AP,TP>>
: public TraceableVectorOperations<JS::Handle<TraceableVector<T,N,AP,TP>>, T,N,AP,TP>
{
using Vec = TraceableVector<T,N,AP,TP>;
friend class TraceableVectorOperations<JS::Handle<Vec>, T,N,AP,TP>;
const Vec& extract() const {
return *static_cast<const JS::Handle<Vec>*>(this)->address();
}
};
{};
template <typename T, size_t N, typename AP, typename TP>
class PersistentRootedBase<TraceableVector<T,N,AP,TP>>
: public MutableTraceableVectorOperations<JS::PersistentRooted<TraceableVector<T,N,AP,TP>>,
T,N,AP,TP>
{
using Vec = TraceableVector<T,N,AP,TP>;
friend class TraceableVectorOperations<JS::PersistentRooted<Vec>, T,N,AP,TP>;
const Vec& extract() const {
return *static_cast<const JS::PersistentRooted<Vec>*>(this)->address();
}
friend class MutableTraceableVectorOperations<JS::PersistentRooted<Vec>, T,N,AP,TP>;
Vec& extract() { return *static_cast<JS::PersistentRooted<Vec>*>(this)->address(); }
};
{};
} // namespace js

View File

@ -1676,82 +1676,82 @@ template <class Outer> class MutableValueOperations;
/*
* A class designed for CRTP use in implementing the non-mutating parts of the
* Value interface in Value-like classes. Outer must be a class inheriting
* ValueOperations<Outer> with a visible extract() method returning the
* const Value* abstracted by Outer.
* ValueOperations<Outer> with a visible get() method returning a const
* reference to the Value abstracted by Outer.
*/
template <class Outer>
class ValueOperations
{
friend class MutableValueOperations<Outer>;
const JS::Value * value() const { return static_cast<const Outer*>(this)->extract(); }
const JS::Value& value() const { return static_cast<const Outer*>(this)->get(); }
public:
bool isUndefined() const { return value()->isUndefined(); }
bool isNull() const { return value()->isNull(); }
bool isBoolean() const { return value()->isBoolean(); }
bool isTrue() const { return value()->isTrue(); }
bool isFalse() const { return value()->isFalse(); }
bool isNumber() const { return value()->isNumber(); }
bool isInt32() const { return value()->isInt32(); }
bool isInt32(int32_t i32) const { return value()->isInt32(i32); }
bool isDouble() const { return value()->isDouble(); }
bool isString() const { return value()->isString(); }
bool isSymbol() const { return value()->isSymbol(); }
bool isObject() const { return value()->isObject(); }
bool isMagic() const { return value()->isMagic(); }
bool isMagic(JSWhyMagic why) const { return value()->isMagic(why); }
bool isMarkable() const { return value()->isMarkable(); }
bool isPrimitive() const { return value()->isPrimitive(); }
bool isGCThing() const { return value()->isGCThing(); }
bool isUndefined() const { return value().isUndefined(); }
bool isNull() const { return value().isNull(); }
bool isBoolean() const { return value().isBoolean(); }
bool isTrue() const { return value().isTrue(); }
bool isFalse() const { return value().isFalse(); }
bool isNumber() const { return value().isNumber(); }
bool isInt32() const { return value().isInt32(); }
bool isInt32(int32_t i32) const { return value().isInt32(i32); }
bool isDouble() const { return value().isDouble(); }
bool isString() const { return value().isString(); }
bool isSymbol() const { return value().isSymbol(); }
bool isObject() const { return value().isObject(); }
bool isMagic() const { return value().isMagic(); }
bool isMagic(JSWhyMagic why) const { return value().isMagic(why); }
bool isMarkable() const { return value().isMarkable(); }
bool isPrimitive() const { return value().isPrimitive(); }
bool isGCThing() const { return value().isGCThing(); }
bool isNullOrUndefined() const { return value()->isNullOrUndefined(); }
bool isObjectOrNull() const { return value()->isObjectOrNull(); }
bool isNullOrUndefined() const { return value().isNullOrUndefined(); }
bool isObjectOrNull() const { return value().isObjectOrNull(); }
bool toBoolean() const { return value()->toBoolean(); }
double toNumber() const { return value()->toNumber(); }
int32_t toInt32() const { return value()->toInt32(); }
double toDouble() const { return value()->toDouble(); }
JSString* toString() const { return value()->toString(); }
JS::Symbol* toSymbol() const { return value()->toSymbol(); }
JSObject& toObject() const { return value()->toObject(); }
JSObject* toObjectOrNull() const { return value()->toObjectOrNull(); }
gc::Cell* toGCThing() const { return value()->toGCThing(); }
JS::TraceKind traceKind() const { return value()->traceKind(); }
uint64_t asRawBits() const { return value()->asRawBits(); }
bool toBoolean() const { return value().toBoolean(); }
double toNumber() const { return value().toNumber(); }
int32_t toInt32() const { return value().toInt32(); }
double toDouble() const { return value().toDouble(); }
JSString* toString() const { return value().toString(); }
JS::Symbol* toSymbol() const { return value().toSymbol(); }
JSObject& toObject() const { return value().toObject(); }
JSObject* toObjectOrNull() const { return value().toObjectOrNull(); }
gc::Cell* toGCThing() const { return value().toGCThing(); }
JS::TraceKind traceKind() const { return value().traceKind(); }
uint64_t asRawBits() const { return value().asRawBits(); }
JSValueType extractNonDoubleType() const { return value()->extractNonDoubleType(); }
uint32_t toPrivateUint32() const { return value()->toPrivateUint32(); }
JSValueType extractNonDoubleType() const { return value().extractNonDoubleType(); }
uint32_t toPrivateUint32() const { return value().toPrivateUint32(); }
JSWhyMagic whyMagic() const { return value()->whyMagic(); }
uint32_t magicUint32() const { return value()->magicUint32(); }
JSWhyMagic whyMagic() const { return value().whyMagic(); }
uint32_t magicUint32() const { return value().magicUint32(); }
};
/*
* A class designed for CRTP use in implementing all the mutating parts of the
* Value interface in Value-like classes. Outer must be a class inheriting
* MutableValueOperations<Outer> with visible extractMutable() and extract()
* methods returning the const Value* and Value* abstracted by Outer.
* MutableValueOperations<Outer> with visible get() methods returning const and
* non-const references to the Value abstracted by Outer.
*/
template <class Outer>
class MutableValueOperations : public ValueOperations<Outer>
{
JS::Value * value() { return static_cast<Outer*>(this)->extractMutable(); }
JS::Value& value() { return static_cast<Outer*>(this)->get(); }
public:
void setNull() { value()->setNull(); }
void setUndefined() { value()->setUndefined(); }
void setInt32(int32_t i) { value()->setInt32(i); }
void setDouble(double d) { value()->setDouble(d); }
void setNull() { value().setNull(); }
void setUndefined() { value().setUndefined(); }
void setInt32(int32_t i) { value().setInt32(i); }
void setDouble(double d) { value().setDouble(d); }
void setNaN() { setDouble(JS::GenericNaN()); }
void setBoolean(bool b) { value()->setBoolean(b); }
void setMagic(JSWhyMagic why) { value()->setMagic(why); }
bool setNumber(uint32_t ui) { return value()->setNumber(ui); }
bool setNumber(double d) { return value()->setNumber(d); }
void setString(JSString* str) { this->value()->setString(str); }
void setSymbol(JS::Symbol* sym) { this->value()->setSymbol(sym); }
void setObject(JSObject& obj) { this->value()->setObject(obj); }
void setObjectOrNull(JSObject* arg) { this->value()->setObjectOrNull(arg); }
void setBoolean(bool b) { value().setBoolean(b); }
void setMagic(JSWhyMagic why) { value().setMagic(why); }
bool setNumber(uint32_t ui) { return value().setNumber(ui); }
bool setNumber(double d) { return value().setNumber(d); }
void setString(JSString* str) { this->value().setString(str); }
void setSymbol(JS::Symbol* sym) { this->value().setSymbol(sym); }
void setObject(JSObject& obj) { this->value().setObject(obj); }
void setObjectOrNull(JSObject* arg) { this->value().setObjectOrNull(arg); }
};
/*
@ -1765,8 +1765,6 @@ class HeapBase<JS::Value> : public ValueOperations<JS::Heap<JS::Value> >
friend class ValueOperations<Outer>;
const JS::Value * extract() const { return static_cast<const Outer*>(this)->address(); }
void setBarriered(const JS::Value& v) {
*static_cast<JS::Heap<JS::Value>*>(this) = v;
}
@ -1812,72 +1810,21 @@ class HeapBase<JS::Value> : public ValueOperations<JS::Heap<JS::Value> >
}
};
/*
* Augment the generic Handle<T> interface when T = Value with type-querying
* and value-extracting operations.
*/
template <>
class HandleBase<JS::Value> : public ValueOperations<JS::Handle<JS::Value> >
{
friend class ValueOperations<JS::Handle<JS::Value> >;
const JS::Value * extract() const {
return static_cast<const JS::Handle<JS::Value>*>(this)->address();
}
};
{};
/*
* Augment the generic MutableHandle<T> interface when T = Value with
* type-querying, value-extracting, and mutating operations.
*/
template <>
class MutableHandleBase<JS::Value> : public MutableValueOperations<JS::MutableHandle<JS::Value> >
{
friend class ValueOperations<JS::MutableHandle<JS::Value> >;
const JS::Value * extract() const {
return static_cast<const JS::MutableHandle<JS::Value>*>(this)->address();
}
{};
friend class MutableValueOperations<JS::MutableHandle<JS::Value> >;
JS::Value * extractMutable() {
return static_cast<JS::MutableHandle<JS::Value>*>(this)->address();
}
};
/*
* Augment the generic Rooted<T> interface when T = Value with type-querying,
* value-extracting, and mutating operations.
*/
template <>
class RootedBase<JS::Value> : public MutableValueOperations<JS::Rooted<JS::Value> >
{
friend class ValueOperations<JS::Rooted<JS::Value> >;
const JS::Value * extract() const {
return static_cast<const JS::Rooted<JS::Value>*>(this)->address();
}
{};
friend class MutableValueOperations<JS::Rooted<JS::Value> >;
JS::Value * extractMutable() {
return static_cast<JS::Rooted<JS::Value>*>(this)->address();
}
};
/*
* Augment the generic PersistentRooted<T> interface when T = Value with type-querying,
* value-extracting, and mutating operations.
*/
template <>
class PersistentRootedBase<JS::Value> : public MutableValueOperations<JS::PersistentRooted<JS::Value>>
{
friend class ValueOperations<JS::PersistentRooted<JS::Value>>;
const JS::Value * extract() const {
return static_cast<const JS::PersistentRooted<JS::Value>*>(this)->address();
}
friend class MutableValueOperations<JS::PersistentRooted<JS::Value>>;
JS::Value * extractMutable() {
return static_cast<JS::PersistentRooted<JS::Value>*>(this)->address();
}
};
{};
/*
* If the Value is a GC pointer type, convert to that type and call |f| with

View File

@ -342,12 +342,7 @@ class BarrieredBase : public BarrieredBaseMixins<T>
template <>
class BarrieredBaseMixins<JS::Value> : public ValueOperations<BarrieredBase<JS::Value> >
{
friend class ValueOperations<BarrieredBase<JS::Value> >;
const JS::Value * extract() const {
return static_cast<const BarrieredBase<JS::Value>*>(this)->unsafeGet();
}
};
{};
/*
* PreBarriered only automatically handles pre-barriers. Post-barriers must

View File

@ -2437,20 +2437,20 @@ namespace JS {
template <typename Outer>
class PropertyDescriptorOperations
{
const JSPropertyDescriptor* desc() const { return static_cast<const Outer*>(this)->extract(); }
const JSPropertyDescriptor& desc() const { return static_cast<const Outer*>(this)->get(); }
bool has(unsigned bit) const {
MOZ_ASSERT(bit != 0);
MOZ_ASSERT((bit & (bit - 1)) == 0); // only a single bit
return (desc()->attrs & bit) != 0;
return (desc().attrs & bit) != 0;
}
bool hasAny(unsigned bits) const {
return (desc()->attrs & bits) != 0;
return (desc().attrs & bits) != 0;
}
bool hasAll(unsigned bits) const {
return (desc()->attrs & bits) == bits;
return (desc().attrs & bits) == bits;
}
// Non-API attributes bit used internally for arguments objects.
@ -2461,7 +2461,7 @@ class PropertyDescriptorOperations
// descriptors. It's complicated.
bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); }
bool isGenericDescriptor() const {
return (desc()->attrs&
return (desc().attrs&
(JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) ==
(JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE);
}
@ -2475,7 +2475,7 @@ class PropertyDescriptorOperations
bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); }
JS::HandleValue value() const {
return JS::HandleValue::fromMarkedLocation(&desc()->value);
return JS::HandleValue::fromMarkedLocation(&desc().value);
}
bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); }
@ -2485,24 +2485,24 @@ class PropertyDescriptorOperations
JS::HandleObject getterObject() const {
MOZ_ASSERT(hasGetterObject());
return JS::HandleObject::fromMarkedLocation(
reinterpret_cast<JSObject* const*>(&desc()->getter));
reinterpret_cast<JSObject* const*>(&desc().getter));
}
bool hasSetterObject() const { return has(JSPROP_SETTER); }
JS::HandleObject setterObject() const {
MOZ_ASSERT(hasSetterObject());
return JS::HandleObject::fromMarkedLocation(
reinterpret_cast<JSObject* const*>(&desc()->setter));
reinterpret_cast<JSObject* const*>(&desc().setter));
}
bool hasGetterOrSetter() const { return desc()->getter || desc()->setter; }
bool hasGetterOrSetter() const { return desc().getter || desc().setter; }
bool isShared() const { return has(JSPROP_SHARED); }
JS::HandleObject object() const {
return JS::HandleObject::fromMarkedLocation(&desc()->obj);
return JS::HandleObject::fromMarkedLocation(&desc().obj);
}
unsigned attributes() const { return desc()->attrs; }
JSGetterOp getter() const { return desc()->getter; }
JSSetterOp setter() const { return desc()->setter; }
unsigned attributes() const { return desc().attrs; }
JSGetterOp getter() const { return desc().getter; }
JSSetterOp setter() const { return desc().setter; }
void assertValid() const {
#ifdef DEBUG
@ -2569,7 +2569,7 @@ class PropertyDescriptorOperations
template <typename Outer>
class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
{
JSPropertyDescriptor * desc() { return static_cast<Outer*>(this)->extractMutable(); }
JSPropertyDescriptor& desc() { return static_cast<Outer*>(this)->get(); }
public:
void clear() {
@ -2615,63 +2615,63 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<
}
JS::MutableHandleObject object() {
return JS::MutableHandleObject::fromMarkedLocation(&desc()->obj);
return JS::MutableHandleObject::fromMarkedLocation(&desc().obj);
}
unsigned& attributesRef() { return desc()->attrs; }
JSGetterOp& getter() { return desc()->getter; }
JSSetterOp& setter() { return desc()->setter; }
unsigned& attributesRef() { return desc().attrs; }
JSGetterOp& getter() { return desc().getter; }
JSSetterOp& setter() { return desc().setter; }
JS::MutableHandleValue value() {
return JS::MutableHandleValue::fromMarkedLocation(&desc()->value);
return JS::MutableHandleValue::fromMarkedLocation(&desc().value);
}
void setValue(JS::HandleValue v) {
MOZ_ASSERT(!(desc()->attrs & (JSPROP_GETTER | JSPROP_SETTER)));
MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
attributesRef() &= ~JSPROP_IGNORE_VALUE;
value().set(v);
}
void setConfigurable(bool configurable) {
setAttributes((desc()->attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) |
setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) |
(configurable ? 0 : JSPROP_PERMANENT));
}
void setEnumerable(bool enumerable) {
setAttributes((desc()->attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) |
setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) |
(enumerable ? JSPROP_ENUMERATE : 0));
}
void setWritable(bool writable) {
MOZ_ASSERT(!(desc()->attrs & (JSPROP_GETTER | JSPROP_SETTER)));
setAttributes((desc()->attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) |
MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) |
(writable ? 0 : JSPROP_READONLY));
}
void setAttributes(unsigned attrs) { desc()->attrs = attrs; }
void setAttributes(unsigned attrs) { desc().attrs = attrs; }
void setGetter(JSGetterOp op) {
MOZ_ASSERT(op != JS_PropertyStub);
desc()->getter = op;
desc().getter = op;
}
void setSetter(JSSetterOp op) {
MOZ_ASSERT(op != JS_StrictPropertyStub);
desc()->setter = op;
desc().setter = op;
}
void setGetterObject(JSObject* obj) {
desc()->getter = reinterpret_cast<JSGetterOp>(obj);
desc()->attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
desc()->attrs |= JSPROP_GETTER | JSPROP_SHARED;
desc().getter = reinterpret_cast<JSGetterOp>(obj);
desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
desc().attrs |= JSPROP_GETTER | JSPROP_SHARED;
}
void setSetterObject(JSObject* obj) {
desc()->setter = reinterpret_cast<JSSetterOp>(obj);
desc()->attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
desc()->attrs |= JSPROP_SETTER | JSPROP_SHARED;
desc().setter = reinterpret_cast<JSSetterOp>(obj);
desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
desc().attrs |= JSPROP_SETTER | JSPROP_SHARED;
}
JS::MutableHandleObject getterObject() {
MOZ_ASSERT(this->hasGetterObject());
return JS::MutableHandleObject::fromMarkedLocation(
reinterpret_cast<JSObject**>(&desc()->getter));
reinterpret_cast<JSObject**>(&desc().getter));
}
JS::MutableHandleObject setterObject() {
MOZ_ASSERT(this->hasSetterObject());
return JS::MutableHandleObject::fromMarkedLocation(
reinterpret_cast<JSObject**>(&desc()->setter));
reinterpret_cast<JSObject**>(&desc().setter));
}
};
@ -2682,40 +2682,17 @@ namespace js {
template <>
class RootedBase<JSPropertyDescriptor>
: public JS::MutablePropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor>>
{
friend class JS::PropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor>>;
friend class JS::MutablePropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor>>;
const JSPropertyDescriptor* extract() const {
return static_cast<const JS::Rooted<JSPropertyDescriptor>*>(this)->address();
}
JSPropertyDescriptor* extractMutable() {
return static_cast<JS::Rooted<JSPropertyDescriptor>*>(this)->address();
}
};
{};
template <>
class HandleBase<JSPropertyDescriptor>
: public JS::PropertyDescriptorOperations<JS::Handle<JSPropertyDescriptor>>
{
friend class JS::PropertyDescriptorOperations<JS::Handle<JSPropertyDescriptor>>;
const JSPropertyDescriptor* extract() const {
return static_cast<const JS::Handle<JSPropertyDescriptor>*>(this)->address();
}
};
{};
template <>
class MutableHandleBase<JSPropertyDescriptor>
: public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor>>
{
friend class JS::PropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor>>;
friend class JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor>>;
const JSPropertyDescriptor* extract() const {
return static_cast<const JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
}
JSPropertyDescriptor* extractMutable() {
return static_cast<JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
}
};
{};
} /* namespace js */

View File

@ -349,7 +349,7 @@ class Bindings : public JS::Traceable
template <class Outer>
class BindingsOperations
{
const Bindings& bindings() const { return static_cast<const Outer*>(this)->extract(); }
const Bindings& bindings() const { return static_cast<const Outer*>(this)->get(); }
public:
// Direct data access to the underlying bindings.
@ -413,7 +413,7 @@ class BindingsOperations
template <class Outer>
class MutableBindingsOperations : public BindingsOperations<Outer>
{
Bindings& bindings() { return static_cast<Outer*>(this)->extractMutable(); }
Bindings& bindings() { return static_cast<Outer*>(this)->get(); }
public:
void setCallObjShape(HandleShape shape) { bindings().callObjShape_ = shape; }
@ -438,27 +438,12 @@ class MutableBindingsOperations : public BindingsOperations<Outer>
template <>
class HandleBase<Bindings> : public BindingsOperations<JS::Handle<Bindings>>
{
friend class BindingsOperations<JS::Handle<Bindings>>;
const Bindings& extract() const {
return static_cast<const JS::Handle<Bindings>*>(this)->get();
}
};
{};
template <>
class MutableHandleBase<Bindings>
: public MutableBindingsOperations<JS::MutableHandle<Bindings>>
{
friend class BindingsOperations<JS::MutableHandle<Bindings>>;
const Bindings& extract() const {
return static_cast<const JS::MutableHandle<Bindings>*>(this)->get();
}
friend class MutableBindingsOperations<JS::MutableHandle<Bindings>>;
Bindings& extractMutable() {
return static_cast<JS::MutableHandle<Bindings>*>(this)->get();
}
};
{};
class ScriptCounts
{

View File

@ -1770,12 +1770,7 @@ class ReservedRooted : public ReservedRootedBase<T>
template <>
class ReservedRootedBase<Value> : public ValueOperations<ReservedRooted<Value>>
{
friend class ValueOperations<ReservedRooted<Value>>;
const Value* extract() const {
return static_cast<const ReservedRooted<Value>*>(this)->address();
}
};
{};
static MOZ_NEVER_INLINE bool
Interpret(JSContext* cx, RunState& state)

View File

@ -81,36 +81,26 @@ template <> struct GCMethods<TaggedProto>
template<class Outer>
class TaggedProtoOperations
{
const TaggedProto* value() const {
return static_cast<const Outer*>(this)->extract();
const TaggedProto& value() const {
return static_cast<const Outer*>(this)->get();
}
public:
uintptr_t toWord() const { return value()->toWord(); }
inline bool isLazy() const { return value()->isLazy(); }
inline bool isObject() const { return value()->isObject(); }
inline JSObject* toObject() const { return value()->toObject(); }
inline JSObject* toObjectOrNull() const { return value()->toObjectOrNull(); }
JSObject* raw() const { return value()->raw(); }
uintptr_t toWord() const { return value().toWord(); }
inline bool isLazy() const { return value().isLazy(); }
inline bool isObject() const { return value().isObject(); }
inline JSObject* toObject() const { return value().toObject(); }
inline JSObject* toObjectOrNull() const { return value().toObjectOrNull(); }
JSObject* raw() const { return value().raw(); }
};
template <>
class HandleBase<TaggedProto> : public TaggedProtoOperations<Handle<TaggedProto> >
{
friend class TaggedProtoOperations<Handle<TaggedProto> >;
const TaggedProto * extract() const {
return static_cast<const Handle<TaggedProto>*>(this)->address();
}
};
{};
template <>
class RootedBase<TaggedProto> : public TaggedProtoOperations<Rooted<TaggedProto> >
{
friend class TaggedProtoOperations<Rooted<TaggedProto> >;
const TaggedProto* extract() const {
return static_cast<const Rooted<TaggedProto>*>(this)->address();
}
};
{};
// Since JSObject pointers are either nullptr or a valid object and since the
// object layout of TaggedProto is identical to a bare object pointer, we can