mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-22 23:27:30 +09:00
Issue #1742 - Part 1: Refactor rooting base class templates
Based on Bug 1325406
This commit is contained in:
parent
2f81312755
commit
80d7d43961
24 changed files with 239 additions and 512 deletions
|
|
@ -50,21 +50,12 @@ struct GCPolicy<mozilla::OwningNonNull<T>>
|
||||||
} // namespace JS
|
} // namespace JS
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
template<typename T>
|
template<typename T, typename Wrapper>
|
||||||
struct RootedBase<mozilla::OwningNonNull<T>>
|
struct WrappedPtrOperations<mozilla::OwningNonNull<T>, Wrapper>
|
||||||
{
|
{
|
||||||
typedef mozilla::OwningNonNull<T> SmartPtrType;
|
|
||||||
|
|
||||||
operator SmartPtrType& () const
|
|
||||||
{
|
|
||||||
auto& self = *static_cast<const JS::Rooted<SmartPtrType>*>(this);
|
|
||||||
return self.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T& () const
|
operator T& () const
|
||||||
{
|
{
|
||||||
auto& self = *static_cast<const JS::Rooted<SmartPtrType>*>(this);
|
return static_cast<const Wrapper*>(this)->get();
|
||||||
return self.get();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
|
||||||
|
|
@ -38,19 +38,12 @@ struct GCPolicy<RefPtr<T>>
|
||||||
} // namespace JS
|
} // namespace JS
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
template<typename T>
|
template<typename T, typename Wrapper>
|
||||||
struct RootedBase<RefPtr<T>>
|
struct WrappedPtrOperations<RefPtr<T>, Wrapper>
|
||||||
{
|
{
|
||||||
operator RefPtr<T>& () const
|
|
||||||
{
|
|
||||||
auto& self = *static_cast<const JS::Rooted<RefPtr<T>>*>(this);
|
|
||||||
return self.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T*() const
|
operator T*() const
|
||||||
{
|
{
|
||||||
auto& self = *static_cast<const JS::Rooted<RefPtr<T>>*>(this);
|
return static_cast<const Wrapper*>(this)->get();
|
||||||
return self.get();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
|
||||||
|
|
@ -126,15 +126,15 @@ struct IsHeapConstructibleType<nsXBLMaybeCompiled<T>>
|
||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class UncompiledT>
|
template <class UncompiledT, class Wrapper>
|
||||||
class HeapBase<nsXBLMaybeCompiled<UncompiledT>>
|
class HeapBase<nsXBLMaybeCompiled<UncompiledT>, Wrapper>
|
||||||
{
|
{
|
||||||
const JS::Heap<nsXBLMaybeCompiled<UncompiledT>>& wrapper() const {
|
const Wrapper& wrapper() const {
|
||||||
return *static_cast<const JS::Heap<nsXBLMaybeCompiled<UncompiledT>>*>(this);
|
return *static_cast<const Wrapper*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Heap<nsXBLMaybeCompiled<UncompiledT>>& wrapper() {
|
Wrapper& wrapper() {
|
||||||
return *static_cast<JS::Heap<nsXBLMaybeCompiled<UncompiledT>>*>(this);
|
return *static_cast<Wrapper*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsXBLMaybeCompiled<UncompiledT>* extract() const {
|
const nsXBLMaybeCompiled<UncompiledT>* extract() const {
|
||||||
|
|
|
||||||
|
|
@ -133,13 +133,13 @@ class GCRekeyableHashMap : public JS::GCHashMap<Key, Value, HashPolicy, AllocPol
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename... Args>
|
template <typename Wrapper, typename... Args>
|
||||||
class GCHashMapOperations
|
class WrappedPtrOperations<JS::GCHashMap<Args...>, Wrapper>
|
||||||
{
|
{
|
||||||
using Map = JS::GCHashMap<Args...>;
|
using Map = JS::GCHashMap<Args...>;
|
||||||
using Lookup = typename Map::Lookup;
|
using Lookup = typename Map::Lookup;
|
||||||
|
|
||||||
const Map& map() const { return static_cast<const Outer*>(this)->get(); }
|
const Map& map() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using AddPtr = typename Map::AddPtr;
|
using AddPtr = typename Map::AddPtr;
|
||||||
|
|
@ -162,18 +162,18 @@ class GCHashMapOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename... Args>
|
template <typename Wrapper, typename... Args>
|
||||||
class MutableGCHashMapOperations
|
class MutableWrappedPtrOperations<JS::GCHashMap<Args...>, Wrapper>
|
||||||
: public GCHashMapOperations<Outer, Args...>
|
: public WrappedPtrOperations<JS::GCHashMap<Args...>, Wrapper>
|
||||||
{
|
{
|
||||||
using Map = JS::GCHashMap<Args...>;
|
using Map = JS::GCHashMap<Args...>;
|
||||||
using Lookup = typename Map::Lookup;
|
using Lookup = typename Map::Lookup;
|
||||||
|
|
||||||
Map& map() { return static_cast<Outer*>(this)->get(); }
|
Map& map() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using AddPtr = typename Map::AddPtr;
|
using AddPtr = typename Map::AddPtr;
|
||||||
struct Enum : public Map::Enum { explicit Enum(Outer& o) : Map::Enum(o.map()) {} };
|
struct Enum : public Map::Enum { explicit Enum(Wrapper& o) : Map::Enum(o.map()) {} };
|
||||||
using Ptr = typename Map::Ptr;
|
using Ptr = typename Map::Ptr;
|
||||||
using Range = typename Map::Range;
|
using Range = typename Map::Range;
|
||||||
|
|
||||||
|
|
@ -210,26 +210,6 @@ class MutableGCHashMapOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename A, typename B, typename C, typename D, typename E>
|
|
||||||
class RootedBase<JS::GCHashMap<A,B,C,D,E>>
|
|
||||||
: public MutableGCHashMapOperations<JS::Rooted<JS::GCHashMap<A,B,C,D,E>>, A,B,C,D,E>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C, typename D, typename E>
|
|
||||||
class MutableHandleBase<JS::GCHashMap<A,B,C,D,E>>
|
|
||||||
: public MutableGCHashMapOperations<JS::MutableHandle<JS::GCHashMap<A,B,C,D,E>>, A,B,C,D,E>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C, typename D, typename E>
|
|
||||||
class HandleBase<JS::GCHashMap<A,B,C,D,E>>
|
|
||||||
: public GCHashMapOperations<JS::Handle<JS::GCHashMap<A,B,C,D,E>>, A,B,C,D,E>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C, typename D, typename E>
|
|
||||||
class WeakCacheBase<JS::GCHashMap<A,B,C,D,E>>
|
|
||||||
: public MutableGCHashMapOperations<JS::WeakCache<JS::GCHashMap<A,B,C,D,E>>, A,B,C,D,E>
|
|
||||||
{};
|
|
||||||
|
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
@ -291,13 +271,13 @@ class GCHashSet : public js::HashSet<T, HashPolicy, AllocPolicy>
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
template <typename Outer, typename... Args>
|
template <typename Wrapper, typename... Args>
|
||||||
class GCHashSetOperations
|
class WrappedPtrOperations<JS::GCHashSet<Args...>, Wrapper>
|
||||||
{
|
{
|
||||||
using Set = JS::GCHashSet<Args...>;
|
using Set = JS::GCHashSet<Args...>;
|
||||||
using Lookup = typename Set::Lookup;
|
using Lookup = typename Set::Lookup;
|
||||||
|
|
||||||
const Set& set() const { return static_cast<const Outer*>(this)->get(); }
|
const Set& set() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using AddPtr = typename Set::AddPtr;
|
using AddPtr = typename Set::AddPtr;
|
||||||
|
|
@ -321,19 +301,19 @@ class GCHashSetOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename... Args>
|
template <typename Wrapper, typename... Args>
|
||||||
class MutableGCHashSetOperations
|
class MutableWrappedPtrOperations<JS::GCHashSet<Args...>, Wrapper>
|
||||||
: public GCHashSetOperations<Outer, Args...>
|
: public WrappedPtrOperations<JS::GCHashSet<Args...>, Wrapper>
|
||||||
{
|
{
|
||||||
using Set = JS::GCHashSet<Args...>;
|
using Set = JS::GCHashSet<Args...>;
|
||||||
using Lookup = typename Set::Lookup;
|
using Lookup = typename Set::Lookup;
|
||||||
|
|
||||||
Set& set() { return static_cast<Outer*>(this)->get(); }
|
Set& set() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using AddPtr = typename Set::AddPtr;
|
using AddPtr = typename Set::AddPtr;
|
||||||
using Entry = typename Set::Entry;
|
using Entry = typename Set::Entry;
|
||||||
struct Enum : public Set::Enum { explicit Enum(Outer& o) : Set::Enum(o.set()) {} };
|
struct Enum : public Set::Enum { explicit Enum(Wrapper& o) : Set::Enum(o.set()) {} };
|
||||||
using Ptr = typename Set::Ptr;
|
using Ptr = typename Set::Ptr;
|
||||||
using Range = typename Set::Range;
|
using Range = typename Set::Range;
|
||||||
|
|
||||||
|
|
@ -369,30 +349,6 @@ class MutableGCHashSetOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename HP, typename AP>
|
|
||||||
class RootedBase<JS::GCHashSet<T, HP, AP>>
|
|
||||||
: public MutableGCHashSetOperations<JS::Rooted<JS::GCHashSet<T, HP, AP>>, T, HP, AP>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename HP, typename AP>
|
|
||||||
class MutableHandleBase<JS::GCHashSet<T, HP, AP>>
|
|
||||||
: public MutableGCHashSetOperations<JS::MutableHandle<JS::GCHashSet<T, HP, AP>>, T, HP, AP>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename HP, typename AP>
|
|
||||||
class HandleBase<JS::GCHashSet<T, HP, AP>>
|
|
||||||
: public GCHashSetOperations<JS::Handle<JS::GCHashSet<T, HP, AP>>, T, HP, AP>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename HP, typename AP>
|
|
||||||
class WeakCacheBase<JS::GCHashSet<T, HP, AP>>
|
|
||||||
: public MutableGCHashSetOperations<JS::WeakCache<JS::GCHashSet<T, HP, AP>>, T, HP, AP>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
#endif /* GCHashTable_h */
|
#endif /* GCHashTable_h */
|
||||||
|
|
|
||||||
|
|
@ -123,13 +123,13 @@ struct GCPolicy<mozilla::Variant<Ts...>>
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
template <typename Outer, typename... Ts>
|
template <typename Wrapper, typename... Ts>
|
||||||
class GCVariantOperations
|
class WrappedPtrOperations<mozilla::Variant<Ts...>, Wrapper>
|
||||||
{
|
{
|
||||||
using Impl = JS::detail::GCVariantImplementation<Ts...>;
|
using Impl = JS::detail::GCVariantImplementation<Ts...>;
|
||||||
using Variant = mozilla::Variant<Ts...>;
|
using Variant = mozilla::Variant<Ts...>;
|
||||||
|
|
||||||
const Variant& variant() const { return static_cast<const Outer*>(this)->get(); }
|
const Variant& variant() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -149,15 +149,15 @@ class GCVariantOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename... Ts>
|
template <typename Wrapper, typename... Ts>
|
||||||
class MutableGCVariantOperations
|
class MutableWrappedPtrOperations<mozilla::Variant<Ts...>, Wrapper>
|
||||||
: public GCVariantOperations<Outer, Ts...>
|
: public WrappedPtrOperations<mozilla::Variant<Ts...>, Wrapper>
|
||||||
{
|
{
|
||||||
using Impl = JS::detail::GCVariantImplementation<Ts...>;
|
using Impl = JS::detail::GCVariantImplementation<Ts...>;
|
||||||
using Variant = mozilla::Variant<Ts...>;
|
using Variant = mozilla::Variant<Ts...>;
|
||||||
|
|
||||||
const Variant& variant() const { return static_cast<const Outer*>(this)->get(); }
|
const Variant& variant() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
Variant& variant() { return static_cast<Outer*>(this)->get(); }
|
Variant& variant() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -172,26 +172,6 @@ class MutableGCVariantOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
class RootedBase<mozilla::Variant<Ts...>>
|
|
||||||
: public MutableGCVariantOperations<JS::Rooted<mozilla::Variant<Ts...>>, Ts...>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
class MutableHandleBase<mozilla::Variant<Ts...>>
|
|
||||||
: public MutableGCVariantOperations<JS::MutableHandle<mozilla::Variant<Ts...>>, Ts...>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
class HandleBase<mozilla::Variant<Ts...>>
|
|
||||||
: public GCVariantOperations<JS::Handle<mozilla::Variant<Ts...>>, Ts...>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
class PersistentRootedBase<mozilla::Variant<Ts...>>
|
|
||||||
: public MutableGCVariantOperations<JS::PersistentRooted<mozilla::Variant<Ts...>>, Ts...>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
#endif // js_GCVariant_h
|
#endif // js_GCVariant_h
|
||||||
|
|
|
||||||
|
|
@ -134,11 +134,11 @@ class GCVector
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy>
|
template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy>
|
||||||
class GCVectorOperations
|
class WrappedPtrOperations<JS::GCVector<T, Capacity, AllocPolicy>, Wrapper>
|
||||||
{
|
{
|
||||||
using Vec = JS::GCVector<T, Capacity, AllocPolicy>;
|
using Vec = JS::GCVector<T, Capacity, AllocPolicy>;
|
||||||
const Vec& vec() const { return static_cast<const Outer*>(this)->get(); }
|
const Vec& vec() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); }
|
const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); }
|
||||||
|
|
@ -154,13 +154,13 @@ class GCVectorOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy>
|
template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy>
|
||||||
class MutableGCVectorOperations
|
class MutableWrappedPtrOperations<JS::GCVector<T, Capacity, AllocPolicy>, Wrapper>
|
||||||
: public GCVectorOperations<Outer, T, Capacity, AllocPolicy>
|
: public WrappedPtrOperations<JS::GCVector<T, Capacity, AllocPolicy>, Wrapper>
|
||||||
{
|
{
|
||||||
using Vec = JS::GCVector<T, Capacity, AllocPolicy>;
|
using Vec = JS::GCVector<T, Capacity, AllocPolicy>;
|
||||||
const Vec& vec() const { return static_cast<const Outer*>(this)->get(); }
|
const Vec& vec() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
Vec& vec() { return static_cast<Outer*>(this)->get(); }
|
Vec& vec() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); }
|
const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); }
|
||||||
|
|
@ -223,26 +223,6 @@ class MutableGCVectorOperations
|
||||||
void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); }
|
void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, size_t N, typename AP>
|
|
||||||
class RootedBase<JS::GCVector<T,N,AP>>
|
|
||||||
: public MutableGCVectorOperations<JS::Rooted<JS::GCVector<T,N,AP>>, T,N,AP>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename T, size_t N, typename AP>
|
|
||||||
class MutableHandleBase<JS::GCVector<T,N,AP>>
|
|
||||||
: public MutableGCVectorOperations<JS::MutableHandle<JS::GCVector<T,N,AP>>, T,N,AP>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename T, size_t N, typename AP>
|
|
||||||
class HandleBase<JS::GCVector<T,N,AP>>
|
|
||||||
: public GCVectorOperations<JS::Handle<JS::GCVector<T,N,AP>>, T,N,AP>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename T, size_t N, typename AP>
|
|
||||||
class PersistentRootedBase<JS::GCVector<T,N,AP>>
|
|
||||||
: public MutableGCVectorOperations<JS::PersistentRooted<JS::GCVector<T,N,AP>>, T,N,AP>
|
|
||||||
{};
|
|
||||||
|
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
#endif // js_GCVector_h
|
#endif // js_GCVector_h
|
||||||
|
|
|
||||||
|
|
@ -112,17 +112,23 @@ template <typename T>
|
||||||
struct BarrierMethods {
|
struct BarrierMethods {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Element, typename Wrapper>
|
||||||
class RootedBase {};
|
class WrappedPtrOperations {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename Element, typename Wrapper>
|
||||||
class HandleBase {};
|
class MutableWrappedPtrOperations : public WrappedPtrOperations<Element, Wrapper> {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename Wrapper>
|
||||||
class MutableHandleBase {};
|
class RootedBase : public MutableWrappedPtrOperations<T, Wrapper> {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename Wrapper>
|
||||||
class HeapBase {};
|
class HandleBase : public WrappedPtrOperations<T, Wrapper> {};
|
||||||
|
|
||||||
|
template <typename T, typename Wrapper>
|
||||||
|
class MutableHandleBase : public MutableWrappedPtrOperations<T, Wrapper> {};
|
||||||
|
|
||||||
|
template <typename T, typename Wrapper>
|
||||||
|
class HeapBase : public MutableWrappedPtrOperations<T, Wrapper> {};
|
||||||
|
|
||||||
// Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope
|
// Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope
|
||||||
template <typename T> struct IsHeapConstructibleType { static constexpr bool value = false; };
|
template <typename T> struct IsHeapConstructibleType { static constexpr bool value = false; };
|
||||||
|
|
@ -132,8 +138,8 @@ FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
|
||||||
FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
|
FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
|
||||||
#undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE
|
#undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename Wrapper>
|
||||||
class PersistentRootedBase {};
|
class PersistentRootedBase : public MutableWrappedPtrOperations<T, Wrapper> {};
|
||||||
|
|
||||||
static void* const ConstNullValue = nullptr;
|
static void* const ConstNullValue = nullptr;
|
||||||
|
|
||||||
|
|
@ -230,7 +236,7 @@ AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell) {}
|
||||||
* Type T must be a public GC pointer type.
|
* Type T must be a public GC pointer type.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase<T>
|
class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase<T, Heap<T>>
|
||||||
{
|
{
|
||||||
// Please note: this can actually also be used by nsXBLMaybeCompiled<T>, for legacy reasons.
|
// Please note: this can actually also be used by nsXBLMaybeCompiled<T>, for legacy reasons.
|
||||||
static_assert(js::IsHeapConstructibleType<T>::value,
|
static_assert(js::IsHeapConstructibleType<T>::value,
|
||||||
|
|
@ -367,7 +373,7 @@ ScriptIsMarkedGray(const Heap<JSScript*>& script)
|
||||||
* - It is not possible to store flag bits in a Heap<T>.
|
* - It is not possible to store flag bits in a Heap<T>.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class TenuredHeap : public js::HeapBase<T>
|
class TenuredHeap : public js::HeapBase<T, TenuredHeap<T>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TenuredHeap() : bits(0) {
|
TenuredHeap() : bits(0) {
|
||||||
|
|
@ -451,7 +457,7 @@ class TenuredHeap : public js::HeapBase<T>
|
||||||
* specialization, define a HandleBase<T> specialization containing them.
|
* specialization, define a HandleBase<T> specialization containing them.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
|
class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T, Handle<T>>
|
||||||
{
|
{
|
||||||
friend class JS::MutableHandle<T>;
|
friend class JS::MutableHandle<T>;
|
||||||
|
|
||||||
|
|
@ -540,7 +546,7 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
|
||||||
* them.
|
* them.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
|
class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T, MutableHandle<T>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline MOZ_IMPLICIT MutableHandle(Rooted<T>* root);
|
inline MOZ_IMPLICIT MutableHandle(Rooted<T>* root);
|
||||||
|
|
@ -753,7 +759,7 @@ namespace JS {
|
||||||
* specialization, define a RootedBase<T> specialization containing them.
|
* specialization, define a RootedBase<T> specialization containing them.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MOZ_RAII Rooted : public js::RootedBase<T>
|
class MOZ_RAII Rooted : public js::RootedBase<T, Rooted<T>>
|
||||||
{
|
{
|
||||||
inline void registerWithRootLists(js::RootedListHeads& roots) {
|
inline void registerWithRootLists(js::RootedListHeads& roots) {
|
||||||
this->stack = &roots[JS::MapTypeToRootKind<T>::kind];
|
this->stack = &roots[JS::MapTypeToRootKind<T>::kind];
|
||||||
|
|
@ -853,8 +859,8 @@ namespace js {
|
||||||
* Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
|
* Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
|
||||||
* Handle<StringObject*> h = rooted;
|
* Handle<StringObject*> h = rooted;
|
||||||
*/
|
*/
|
||||||
template <>
|
template <typename Container>
|
||||||
class RootedBase<JSObject*>
|
class RootedBase<JSObject*, Container> : public MutableWrappedPtrOperations<JSObject*, Container>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <class U>
|
template <class U>
|
||||||
|
|
@ -871,8 +877,8 @@ class RootedBase<JSObject*>
|
||||||
* Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
|
* Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
|
||||||
* Handle<StringObject*> h = rooted;
|
* Handle<StringObject*> h = rooted;
|
||||||
*/
|
*/
|
||||||
template <>
|
template <typename Container>
|
||||||
class HandleBase<JSObject*>
|
class HandleBase<JSObject*, Container> : public WrappedPtrOperations<JSObject*, Container>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <class U>
|
template <class U>
|
||||||
|
|
@ -881,7 +887,7 @@ class HandleBase<JSObject*>
|
||||||
|
|
||||||
/** Interface substitute for Rooted<T> which does not root the variable's memory. */
|
/** Interface substitute for Rooted<T> which does not root the variable's memory. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MOZ_RAII FakeRooted : public RootedBase<T>
|
class MOZ_RAII FakeRooted : public RootedBase<T, FakeRooted<T>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename CX>
|
template <typename CX>
|
||||||
|
|
@ -908,7 +914,7 @@ class MOZ_RAII FakeRooted : public RootedBase<T>
|
||||||
|
|
||||||
/** Interface substitute for MutableHandle<T> which is not required to point to rooted memory. */
|
/** Interface substitute for MutableHandle<T> which is not required to point to rooted memory. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class FakeMutableHandle : public js::MutableHandleBase<T>
|
class FakeMutableHandle : public js::MutableHandleBase<T, FakeMutableHandle<T>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MOZ_IMPLICIT FakeMutableHandle(T* t) {
|
MOZ_IMPLICIT FakeMutableHandle(T* t) {
|
||||||
|
|
@ -1075,7 +1081,7 @@ MutableHandle<T>::MutableHandle(PersistentRooted<T>* root)
|
||||||
* marked when the object itself is marked.
|
* marked when the object itself is marked.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class PersistentRooted : public js::PersistentRootedBase<T>,
|
class PersistentRooted : public js::RootedBase<T, PersistentRooted<T>>,
|
||||||
private mozilla::LinkedListElement<PersistentRooted<T>>
|
private mozilla::LinkedListElement<PersistentRooted<T>>
|
||||||
{
|
{
|
||||||
using ListBase = mozilla::LinkedListElement<PersistentRooted<T>>;
|
using ListBase = mozilla::LinkedListElement<PersistentRooted<T>>;
|
||||||
|
|
@ -1240,10 +1246,10 @@ class JS_PUBLIC_API(ObjectPtr)
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
template <typename Outer, typename T, typename D>
|
template <typename T, typename D, typename Container>
|
||||||
class UniquePtrOperations
|
class WrappedPtrOperations<UniquePtr<T, D>, Container>
|
||||||
{
|
{
|
||||||
const UniquePtr<T, D>& uniquePtr() const { return static_cast<const Outer*>(this)->get(); }
|
const UniquePtr<T, D>& uniquePtr() const { return static_cast<const Container*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit operator bool() const { return !!uniquePtr(); }
|
explicit operator bool() const { return !!uniquePtr(); }
|
||||||
|
|
@ -1252,36 +1258,17 @@ class UniquePtrOperations
|
||||||
T& operator*() const { return *uniquePtr(); }
|
T& operator*() const { return *uniquePtr(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename T, typename D>
|
template <typename T, typename D, typename Container>
|
||||||
class MutableUniquePtrOperations : public UniquePtrOperations<Outer, T, D>
|
class MutableWrappedPtrOperations<UniquePtr<T, D>, Container>
|
||||||
|
: public WrappedPtrOperations<UniquePtr<T, D>, Container>
|
||||||
{
|
{
|
||||||
UniquePtr<T, D>& uniquePtr() { return static_cast<Outer*>(this)->get(); }
|
UniquePtr<T, D>& uniquePtr() { return static_cast<Container*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MOZ_MUST_USE typename UniquePtr<T, D>::Pointer release() { return uniquePtr().release(); }
|
MOZ_MUST_USE typename UniquePtr<T, D>::Pointer release() { return uniquePtr().release(); }
|
||||||
void reset(T* ptr = T()) { uniquePtr().reset(ptr); }
|
void reset(T* ptr = T()) { uniquePtr().reset(ptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename D>
|
|
||||||
class RootedBase<UniquePtr<T, D>>
|
|
||||||
: public MutableUniquePtrOperations<JS::Rooted<UniquePtr<T, D>>, T, D>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename T, typename D>
|
|
||||||
class MutableHandleBase<UniquePtr<T, D>>
|
|
||||||
: public MutableUniquePtrOperations<JS::MutableHandle<UniquePtr<T, D>>, T, D>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename T, typename D>
|
|
||||||
class HandleBase<UniquePtr<T, D>>
|
|
||||||
: public UniquePtrOperations<JS::Handle<UniquePtr<T, D>>, T, D>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename T, typename D>
|
|
||||||
class PersistentRootedBase<UniquePtr<T, D>>
|
|
||||||
: public MutableUniquePtrOperations<JS::PersistentRooted<UniquePtr<T, D>>, T, D>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
namespace gc {
|
namespace gc {
|
||||||
|
|
||||||
template <typename T, typename TraceCallbacks>
|
template <typename T, typename TraceCallbacks>
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,6 @@
|
||||||
|
|
||||||
#include "js/HeapAPI.h"
|
#include "js/HeapAPI.h"
|
||||||
|
|
||||||
namespace js {
|
|
||||||
template <typename T>
|
|
||||||
class WeakCacheBase {};
|
|
||||||
} // namespace js
|
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
template <typename T> class WeakCache;
|
template <typename T> class WeakCache;
|
||||||
|
|
||||||
|
|
@ -24,7 +19,7 @@ RegisterWeakCache(JS::Zone* zone, JS::WeakCache<void*>* cachep);
|
||||||
// A WeakCache stores the given Sweepable container and links itself into a
|
// A WeakCache stores the given Sweepable container and links itself into a
|
||||||
// list of such caches that are swept during each GC.
|
// list of such caches that are swept during each GC.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class WeakCache : public js::WeakCacheBase<T>,
|
class WeakCache : public js::MutableWrappedPtrOperations<T, WeakCache<T>>,
|
||||||
private mozilla::LinkedListElement<WeakCache<T>>
|
private mozilla::LinkedListElement<WeakCache<T>>
|
||||||
{
|
{
|
||||||
friend class mozilla::LinkedListElement<WeakCache<T>>;
|
friend class mozilla::LinkedListElement<WeakCache<T>>;
|
||||||
|
|
|
||||||
|
|
@ -1340,20 +1340,18 @@ struct BarrierMethods<JS::Value>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Outer> class MutableValueOperations;
|
template <class Wrapper> class MutableValueOperations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class designed for CRTP use in implementing the non-mutating parts of the
|
* 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
|
* Value interface in Value-like classes. Wrapper must be a class inheriting
|
||||||
* ValueOperations<Outer> with a visible get() method returning a const
|
* ValueOperations<Wrapper> with a visible get() method returning a const
|
||||||
* reference to the Value abstracted by Outer.
|
* reference to the Value abstracted by Wrapper.
|
||||||
*/
|
*/
|
||||||
template <class Outer>
|
template <class Wrapper>
|
||||||
class ValueOperations
|
class WrappedPtrOperations<JS::Value, Wrapper>
|
||||||
{
|
{
|
||||||
friend class MutableValueOperations<Outer>;
|
const JS::Value& value() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
const JS::Value& value() const { return static_cast<const Outer*>(this)->get(); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isUndefined() const { return value().isUndefined(); }
|
bool isUndefined() const { return value().isUndefined(); }
|
||||||
|
|
@ -1398,17 +1396,17 @@ class ValueOperations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class designed for CRTP use in implementing all the mutating parts of the
|
* 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
|
* Value interface in Value-like classes. Wrapper must be a class inheriting
|
||||||
* MutableValueOperations<Outer> with visible get() methods returning const and
|
* MutableWrappedPtrOperations<Wrapper> with visible get() methods returning const and
|
||||||
* non-const references to the Value abstracted by Outer.
|
* non-const references to the Value abstracted by Wrapper.
|
||||||
*/
|
*/
|
||||||
template <class Outer>
|
template <class Wrapper>
|
||||||
class MutableValueOperations : public ValueOperations<Outer>
|
class MutableWrappedPtrOperations<JS::Value, Wrapper> : public WrappedPtrOperations<JS::Value, Wrapper>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void set(const JS::Value& v) {
|
void set(const JS::Value& v) {
|
||||||
// Call Outer::set to trigger any barriers.
|
// Call Outer::set to trigger any barriers.
|
||||||
static_cast<Outer*>(this)->set(v);
|
static_cast<Wrapper*>(this)->set(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1434,13 +1432,9 @@ class MutableValueOperations : public ValueOperations<Outer>
|
||||||
* Augment the generic Heap<T> interface when T = Value with
|
* Augment the generic Heap<T> interface when T = Value with
|
||||||
* type-querying, value-extracting, and mutating operations.
|
* type-querying, value-extracting, and mutating operations.
|
||||||
*/
|
*/
|
||||||
template <>
|
template <typename Wrapper>
|
||||||
class HeapBase<JS::Value> : public MutableValueOperations<JS::Heap<JS::Value> >
|
class HeapBase<JS::Value, Wrapper> : public MutableWrappedPtrOperations<JS::Value, Wrapper>
|
||||||
{
|
{
|
||||||
typedef JS::Heap<JS::Value> Outer;
|
|
||||||
|
|
||||||
friend class ValueOperations<Outer>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setNumber(uint32_t ui) {
|
void setNumber(uint32_t ui) {
|
||||||
if (ui > JSVAL_INT_MAX) {
|
if (ui > JSVAL_INT_MAX) {
|
||||||
|
|
@ -1460,22 +1454,6 @@ class HeapBase<JS::Value> : public MutableValueOperations<JS::Heap<JS::Value> >
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class HandleBase<JS::Value> : public ValueOperations<JS::Handle<JS::Value> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class MutableHandleBase<JS::Value> : public MutableValueOperations<JS::MutableHandle<JS::Value> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class RootedBase<JS::Value> : public MutableValueOperations<JS::Rooted<JS::Value> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class PersistentRootedBase<JS::Value> : public MutableValueOperations<JS::PersistentRooted<JS::Value>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the Value is a GC pointer type, convert to that type and call |f| with
|
* If the Value is a GC pointer type, convert to that type and call |f| with
|
||||||
* the pointer. If the Value is not a GC type, calls F::defaultValue.
|
* the pointer. If the Value is not a GC type, calls F::defaultValue.
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,22 @@ class HashableValue
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <typename Wrapper>
|
||||||
class RootedBase<HashableValue> {
|
class WrappedPtrOperations<HashableValue, Wrapper>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Value value() const {
|
||||||
|
return static_cast<const Wrapper*>(this)->get().get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Wrapper>
|
||||||
|
class MutableWrappedPtrOperations<HashableValue, Wrapper>
|
||||||
|
: public WrappedPtrOperations<HashableValue, Wrapper>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MOZ_MUST_USE bool setValue(JSContext* cx, HandleValue v) {
|
MOZ_MUST_USE bool setValue(JSContext* cx, HandleValue v) {
|
||||||
return static_cast<JS::Rooted<HashableValue>*>(this)->get().setValue(cx, v);
|
return static_cast<Wrapper*>(this)->get().setValue(cx, v);
|
||||||
}
|
|
||||||
Value value() const {
|
|
||||||
return static_cast<const JS::Rooted<HashableValue>*>(this)->get().get();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,11 @@ class TraceableFifo : public js::Fifo<T, MinInlineCapacity, AllocPolicy>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy>
|
template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy>
|
||||||
class TraceableFifoOperations
|
class WrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, Wrapper>
|
||||||
{
|
{
|
||||||
using TF = TraceableFifo<T, Capacity, AllocPolicy>;
|
using TF = TraceableFifo<T, Capacity, AllocPolicy>;
|
||||||
const TF& fifo() const { return static_cast<const Outer*>(this)->extract(); }
|
const TF& fifo() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
size_t length() const { return fifo().length(); }
|
size_t length() const { return fifo().length(); }
|
||||||
|
|
@ -63,12 +63,12 @@ class TraceableFifoOperations
|
||||||
const T& front() const { return fifo().front(); }
|
const T& front() const { return fifo().front(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy>
|
template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy>
|
||||||
class MutableTraceableFifoOperations
|
class MutableWrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, Wrapper>
|
||||||
: public TraceableFifoOperations<Outer, T, Capacity, AllocPolicy>
|
: public WrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, Wrapper>
|
||||||
{
|
{
|
||||||
using TF = TraceableFifo<T, Capacity, AllocPolicy>;
|
using TF = TraceableFifo<T, Capacity, AllocPolicy>;
|
||||||
TF& fifo() { return static_cast<Outer*>(this)->extract(); }
|
TF& fifo() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
T& front() { return fifo().front(); }
|
T& front() { return fifo().front(); }
|
||||||
|
|
@ -82,46 +82,6 @@ class MutableTraceableFifoOperations
|
||||||
void clear() { fifo().clear(); }
|
void clear() { fifo().clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename A, size_t B, typename C>
|
|
||||||
class RootedBase<TraceableFifo<A,B,C>>
|
|
||||||
: public MutableTraceableFifoOperations<JS::Rooted<TraceableFifo<A,B,C>>, A,B,C>
|
|
||||||
{
|
|
||||||
using TF = TraceableFifo<A,B,C>;
|
|
||||||
|
|
||||||
friend class TraceableFifoOperations<JS::Rooted<TF>, A,B,C>;
|
|
||||||
const TF& extract() const { return *static_cast<const JS::Rooted<TF>*>(this)->address(); }
|
|
||||||
|
|
||||||
friend class MutableTraceableFifoOperations<JS::Rooted<TF>, A,B,C>;
|
|
||||||
TF& extract() { return *static_cast<JS::Rooted<TF>*>(this)->address(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, size_t B, typename C>
|
|
||||||
class MutableHandleBase<TraceableFifo<A,B,C>>
|
|
||||||
: public MutableTraceableFifoOperations<JS::MutableHandle<TraceableFifo<A,B,C>>, A,B,C>
|
|
||||||
{
|
|
||||||
using TF = TraceableFifo<A,B,C>;
|
|
||||||
|
|
||||||
friend class TraceableFifoOperations<JS::MutableHandle<TF>, A,B,C>;
|
|
||||||
const TF& extract() const {
|
|
||||||
return *static_cast<const JS::MutableHandle<TF>*>(this)->address();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class MutableTraceableFifoOperations<JS::MutableHandle<TF>, A,B,C>;
|
|
||||||
TF& extract() { return *static_cast<JS::MutableHandle<TF>*>(this)->address(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, size_t B, typename C>
|
|
||||||
class HandleBase<TraceableFifo<A,B,C>>
|
|
||||||
: public TraceableFifoOperations<JS::Handle<TraceableFifo<A,B,C>>, A,B,C>
|
|
||||||
{
|
|
||||||
using TF = TraceableFifo<A,B,C>;
|
|
||||||
|
|
||||||
friend class TraceableFifoOperations<JS::Handle<TF>, A,B,C>;
|
|
||||||
const TF& extract() const {
|
|
||||||
return *static_cast<const JS::Handle<TF>*>(this)->address();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
#endif // js_TraceableFifo_h
|
#endif // js_TraceableFifo_h
|
||||||
|
|
|
||||||
|
|
@ -324,18 +324,12 @@ struct InternalBarrierMethods<jsid>
|
||||||
static void postBarrier(jsid* idp, jsid prev, jsid next) {}
|
static void postBarrier(jsid* idp, jsid prev, jsid next) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Barrier classes can use Mixins to add methods to a set of barrier
|
|
||||||
// instantiations, to make the barriered thing look and feel more like the
|
|
||||||
// thing itself.
|
|
||||||
template <typename T>
|
|
||||||
class BarrieredBaseMixins {};
|
|
||||||
|
|
||||||
// Base class of all barrier types.
|
// Base class of all barrier types.
|
||||||
//
|
//
|
||||||
// This is marked non-memmovable since post barriers added by derived classes
|
// This is marked non-memmovable since post barriers added by derived classes
|
||||||
// can add pointers to class instances to the store buffer.
|
// can add pointers to class instances to the store buffer.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class MOZ_NON_MEMMOVABLE BarrieredBase : public BarrieredBaseMixins<T>
|
class MOZ_NON_MEMMOVABLE BarrieredBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
// BarrieredBase is not directly instantiable.
|
// BarrieredBase is not directly instantiable.
|
||||||
|
|
@ -356,9 +350,12 @@ class MOZ_NON_MEMMOVABLE BarrieredBase : public BarrieredBaseMixins<T>
|
||||||
|
|
||||||
// Base class for barriered pointer types that intercept only writes.
|
// Base class for barriered pointer types that intercept only writes.
|
||||||
template <class T>
|
template <class T>
|
||||||
class WriteBarrieredBase : public BarrieredBase<T>
|
class WriteBarrieredBase : public BarrieredBase<T>,
|
||||||
|
public WrappedPtrOperations<T, WriteBarrieredBase<T>>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
using BarrieredBase<T>::value;
|
||||||
|
|
||||||
// WriteBarrieredBase is not directly instantiable.
|
// WriteBarrieredBase is not directly instantiable.
|
||||||
explicit WriteBarrieredBase(const T& v) : BarrieredBase<T>(v) {}
|
explicit WriteBarrieredBase(const T& v) : BarrieredBase<T>(v) {}
|
||||||
|
|
||||||
|
|
@ -580,8 +577,12 @@ class ReadBarrieredBase : public BarrieredBase<T>
|
||||||
// insert manual post-barriers on the table for rekeying if the key is based in
|
// insert manual post-barriers on the table for rekeying if the key is based in
|
||||||
// any way on the address of the object.
|
// any way on the address of the object.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ReadBarriered : public ReadBarrieredBase<T>
|
class ReadBarriered : public ReadBarrieredBase<T>,
|
||||||
|
public WrappedPtrOperations<T, ReadBarriered<T>>
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
using ReadBarrieredBase<T>::value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReadBarriered() : ReadBarrieredBase<T>(JS::GCPolicy<T>::initial()) {}
|
ReadBarriered() : ReadBarrieredBase<T>(JS::GCPolicy<T>::initial()) {}
|
||||||
|
|
||||||
|
|
@ -649,12 +650,6 @@ class ReadBarriered : public ReadBarrieredBase<T>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using WeakRef = ReadBarriered<T>;
|
using WeakRef = ReadBarriered<T>;
|
||||||
|
|
||||||
// Add Value operations to all Barrier types. Note, this must be defined before
|
|
||||||
// HeapSlot for HeapSlot's base to get these operations.
|
|
||||||
template <>
|
|
||||||
class BarrieredBaseMixins<JS::Value> : public ValueOperations<WriteBarrieredBase<JS::Value>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
// A pre- and post-barriered Value that is specialized to be aware that it
|
// A pre- and post-barriered Value that is specialized to be aware that it
|
||||||
// resides in a slots or elements vector. This allows it to be relocated in
|
// resides in a slots or elements vector. This allows it to be relocated in
|
||||||
// memory, but with substantially less overhead than a HeapPtr.
|
// memory, but with substantially less overhead than a HeapPtr.
|
||||||
|
|
|
||||||
|
|
@ -56,19 +56,10 @@ struct MyContainer
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
template <>
|
template <typename Wrapper>
|
||||||
struct RootedBase<MyContainer> {
|
struct MutableWrappedPtrOperations<MyContainer, Wrapper> {
|
||||||
HeapPtr<JSObject*>& obj() { return static_cast<Rooted<MyContainer>*>(this)->get().obj; }
|
HeapPtr<JSObject*>& obj() { return static_cast<Wrapper*>(this)->get().obj; }
|
||||||
HeapPtr<JSString*>& str() { return static_cast<Rooted<MyContainer>*>(this)->get().str; }
|
HeapPtr<JSString*>& str() { return static_cast<Wrapper*>(this)->get().str; }
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct PersistentRootedBase<MyContainer> {
|
|
||||||
HeapPtr<JSObject*>& obj() {
|
|
||||||
return static_cast<PersistentRooted<MyContainer>*>(this)->get().obj;
|
|
||||||
}
|
|
||||||
HeapPtr<JSString*>& str() {
|
|
||||||
return static_cast<PersistentRooted<MyContainer>*>(this)->get().str;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2546,10 +2546,14 @@ struct JS_PUBLIC_API(PropertyDescriptor) {
|
||||||
void trace(JSTracer* trc);
|
void trace(JSTracer* trc);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
} // namespace JS
|
||||||
class PropertyDescriptorOperations
|
|
||||||
|
namespace js {
|
||||||
|
|
||||||
|
template <typename Wrapper>
|
||||||
|
class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
|
||||||
{
|
{
|
||||||
const PropertyDescriptor& desc() const { return static_cast<const Outer*>(this)->get(); }
|
const JS::PropertyDescriptor& desc() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
bool has(unsigned bit) const {
|
bool has(unsigned bit) const {
|
||||||
MOZ_ASSERT(bit != 0);
|
MOZ_ASSERT(bit != 0);
|
||||||
|
|
@ -2678,10 +2682,11 @@ class PropertyDescriptorOperations
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
template <typename Wrapper>
|
||||||
class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
|
class MutableWrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
|
||||||
|
: public js::WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
|
||||||
{
|
{
|
||||||
PropertyDescriptor& desc() { return static_cast<Outer*>(this)->get(); }
|
JS::PropertyDescriptor& desc() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void clear() {
|
void clear() {
|
||||||
|
|
@ -2692,7 +2697,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<
|
||||||
value().setUndefined();
|
value().setUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initFields(HandleObject obj, HandleValue v, unsigned attrs,
|
void initFields(JS::HandleObject obj, JS::HandleValue v, unsigned attrs,
|
||||||
JSGetterOp getterOp, JSSetterOp setterOp) {
|
JSGetterOp getterOp, JSSetterOp setterOp) {
|
||||||
MOZ_ASSERT(getterOp != JS_PropertyStub);
|
MOZ_ASSERT(getterOp != JS_PropertyStub);
|
||||||
MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
|
MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
|
||||||
|
|
@ -2704,7 +2709,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<
|
||||||
setSetter(setterOp);
|
setSetter(setterOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign(PropertyDescriptor& other) {
|
void assign(JS::PropertyDescriptor& other) {
|
||||||
object().set(other.obj);
|
object().set(other.obj);
|
||||||
setAttributes(other.attrs);
|
setAttributes(other.attrs);
|
||||||
setGetter(other.getter);
|
setGetter(other.getter);
|
||||||
|
|
@ -2712,7 +2717,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<
|
||||||
value().set(other.value);
|
value().set(other.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDataDescriptor(HandleValue v, unsigned attrs) {
|
void setDataDescriptor(JS::HandleValue v, unsigned attrs) {
|
||||||
MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE |
|
MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE |
|
||||||
JSPROP_PERMANENT |
|
JSPROP_PERMANENT |
|
||||||
JSPROP_READONLY |
|
JSPROP_READONLY |
|
||||||
|
|
@ -2787,26 +2792,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace JS */
|
} // namespace js
|
||||||
|
|
||||||
namespace js {
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class RootedBase<JS::PropertyDescriptor>
|
|
||||||
: public JS::MutablePropertyDescriptorOperations<JS::Rooted<JS::PropertyDescriptor>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class HandleBase<JS::PropertyDescriptor>
|
|
||||||
: public JS::PropertyDescriptorOperations<JS::Handle<JS::PropertyDescriptor>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class MutableHandleBase<JS::PropertyDescriptor>
|
|
||||||
: public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JS::PropertyDescriptor>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
} /* namespace js */
|
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -722,8 +722,9 @@ JSCompartment::sweepAfterMinorGC(JSTracer* trc)
|
||||||
{
|
{
|
||||||
globalWriteBarriered = 0;
|
globalWriteBarriered = 0;
|
||||||
|
|
||||||
if (innerViews.needsSweepAfterMinorGC())
|
InnerViewTable& table = innerViews.get();
|
||||||
innerViews.sweepAfterMinorGC();
|
if (table.needsSweepAfterMinorGC())
|
||||||
|
table.sweepAfterMinorGC();
|
||||||
|
|
||||||
crossCompartmentWrappers.sweepAfterMinorGC(trc);
|
crossCompartmentWrappers.sweepAfterMinorGC(trc);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -587,21 +587,23 @@ class JSObject : public js::gc::Cell
|
||||||
void operator=(const JSObject& other) = delete;
|
void operator=(const JSObject& other) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class U>
|
template <typename Wrapper>
|
||||||
|
template <typename U>
|
||||||
MOZ_ALWAYS_INLINE JS::Handle<U*>
|
MOZ_ALWAYS_INLINE JS::Handle<U*>
|
||||||
js::RootedBase<JSObject*>::as() const
|
js::RootedBase<JSObject*, Wrapper>::as() const
|
||||||
{
|
{
|
||||||
const JS::Rooted<JSObject*>& self = *static_cast<const JS::Rooted<JSObject*>*>(this);
|
const Wrapper& self = *static_cast<const Wrapper*>(this);
|
||||||
MOZ_ASSERT(self->is<U>());
|
MOZ_ASSERT(self->template is<U>());
|
||||||
return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address()));
|
return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Wrapper>
|
||||||
template <class U>
|
template <class U>
|
||||||
MOZ_ALWAYS_INLINE JS::Handle<U*>
|
MOZ_ALWAYS_INLINE JS::Handle<U*>
|
||||||
js::HandleBase<JSObject*>::as() const
|
js::HandleBase<JSObject*, Wrapper>::as() const
|
||||||
{
|
{
|
||||||
const JS::Handle<JSObject*>& self = *static_cast<const JS::Handle<JSObject*>*>(this);
|
const JS::Handle<JSObject*>& self = *static_cast<const JS::Handle<JSObject*>*>(this);
|
||||||
MOZ_ASSERT(self->is<U>());
|
MOZ_ASSERT(self->template is<U>());
|
||||||
return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address()));
|
return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ ArrayBufferObject::detach(JSContext* cx, Handle<ArrayBufferObject*> buffer,
|
||||||
// Update all views of the buffer to account for the buffer having been
|
// Update all views of the buffer to account for the buffer having been
|
||||||
// detached, and clear the buffer's data and list of views.
|
// detached, and clear the buffer's data and list of views.
|
||||||
|
|
||||||
auto& innerViews = cx->compartment()->innerViews;
|
auto& innerViews = cx->compartment()->innerViews.get();
|
||||||
if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(buffer)) {
|
if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(buffer)) {
|
||||||
for (size_t i = 0; i < views->length(); i++)
|
for (size_t i = 0; i < views->length(); i++)
|
||||||
NoteViewBufferWasDetached((*views)[i], newContents, cx);
|
NoteViewBufferWasDetached((*views)[i], newContents, cx);
|
||||||
|
|
@ -427,7 +427,7 @@ ArrayBufferObject::changeContents(JSContext* cx, BufferContents newContents,
|
||||||
setNewData(cx->runtime()->defaultFreeOp(), newContents, ownsState);
|
setNewData(cx->runtime()->defaultFreeOp(), newContents, ownsState);
|
||||||
|
|
||||||
// Update all views.
|
// Update all views.
|
||||||
auto& innerViews = cx->compartment()->innerViews;
|
auto& innerViews = cx->compartment()->innerViews.get();
|
||||||
if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(this)) {
|
if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(this)) {
|
||||||
for (size_t i = 0; i < views->length(); i++)
|
for (size_t i = 0; i < views->length(); i++)
|
||||||
changeViewContents(cx, (*views)[i], oldDataPointer, newContents);
|
changeViewContents(cx, (*views)[i], oldDataPointer, newContents);
|
||||||
|
|
|
||||||
|
|
@ -541,7 +541,6 @@ class InnerViewTable
|
||||||
typedef Vector<ArrayBufferViewObject*, 1, SystemAllocPolicy> ViewVector;
|
typedef Vector<ArrayBufferViewObject*, 1, SystemAllocPolicy> ViewVector;
|
||||||
|
|
||||||
friend class ArrayBufferObject;
|
friend class ArrayBufferObject;
|
||||||
friend class WeakCacheBase<InnerViewTable>;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MapGCPolicy {
|
struct MapGCPolicy {
|
||||||
|
|
@ -602,23 +601,15 @@ class InnerViewTable
|
||||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <typename Wrapper>
|
||||||
class WeakCacheBase<InnerViewTable>
|
class MutableWrappedPtrOperations<InnerViewTable, Wrapper>
|
||||||
|
: public WrappedPtrOperations<InnerViewTable, Wrapper>
|
||||||
{
|
{
|
||||||
InnerViewTable& table() {
|
InnerViewTable& table() {
|
||||||
return static_cast<JS::WeakCache<InnerViewTable>*>(this)->get();
|
return static_cast<Wrapper*>(this)->get();
|
||||||
}
|
|
||||||
const InnerViewTable& table() const {
|
|
||||||
return static_cast<const JS::WeakCache<InnerViewTable>*>(this)->get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InnerViewTable::ViewVector* maybeViewsUnbarriered(ArrayBufferObject* obj) {
|
|
||||||
return table().maybeViewsUnbarriered(obj);
|
|
||||||
}
|
|
||||||
void removeViews(ArrayBufferObject* obj) { table().removeViews(obj); }
|
|
||||||
void sweepAfterMinorGC() { table().sweepAfterMinorGC(); }
|
|
||||||
bool needsSweepAfterMinorGC() const { return table().needsSweepAfterMinorGC(); }
|
|
||||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
|
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
|
||||||
return table().sizeOfExcludingThis(mallocSizeOf);
|
return table().sizeOfExcludingThis(mallocSizeOf);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1613,11 +1613,7 @@ GetSuperEnvFunction(JSContext* cx, InterpreterRegs& regs)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class ReservedRootedBase {
|
class ReservedRooted : public RootedBase<T, ReservedRooted<T>>
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class ReservedRooted : public ReservedRootedBase<T>
|
|
||||||
{
|
{
|
||||||
Rooted<T>* savedRoot;
|
Rooted<T>* savedRoot;
|
||||||
|
|
||||||
|
|
@ -1645,14 +1641,6 @@ class ReservedRooted : public ReservedRootedBase<T>
|
||||||
DECLARE_POINTER_ASSIGN_OPS(ReservedRooted, T)
|
DECLARE_POINTER_ASSIGN_OPS(ReservedRooted, T)
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class ReservedRootedBase<Value> : public ValueOperations<ReservedRooted<Value>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class ReservedRootedBase<Scope*> : public ScopeCastOperation<ReservedRooted<Scope*>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
static MOZ_NEVER_INLINE bool
|
static MOZ_NEVER_INLINE bool
|
||||||
Interpret(JSContext* cx, RunState& state)
|
Interpret(JSContext* cx, RunState& state)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -255,10 +255,13 @@ class MOZ_STACK_CLASS JSONParser : public JSONParserBase
|
||||||
void operator=(const JSONParser& other) = delete;
|
void operator=(const JSONParser& other) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT, typename Wrapper>
|
||||||
struct RootedBase<JSONParser<CharT>> {
|
class MutableWrappedPtrOperations<JSONParser<CharT>, Wrapper>
|
||||||
|
: public WrappedPtrOperations<JSONParser<CharT>, Wrapper>
|
||||||
|
{
|
||||||
|
public:
|
||||||
bool parse(MutableHandleValue vp) {
|
bool parse(MutableHandleValue vp) {
|
||||||
return static_cast<Rooted<JSONParser<CharT>>*>(this)->get().parse(vp);
|
return static_cast<Wrapper*>(this)->get().parse(vp);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -265,24 +265,6 @@ class SavedStacks {
|
||||||
uint32_t column;
|
uint32_t column;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
|
||||||
struct LocationValueOperations {
|
|
||||||
JSAtom* source() const { return loc().source; }
|
|
||||||
size_t line() const { return loc().line; }
|
|
||||||
uint32_t column() const { return loc().column; }
|
|
||||||
private:
|
|
||||||
const LocationValue& loc() const { return static_cast<const Outer*>(this)->get(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Outer>
|
|
||||||
struct MutableLocationValueOperations : public LocationValueOperations<Outer> {
|
|
||||||
void setSource(JSAtom* v) { loc().source = v; }
|
|
||||||
void setLine(size_t v) { loc().line = v; }
|
|
||||||
void setColumn(uint32_t v) { loc().column = v; }
|
|
||||||
private:
|
|
||||||
LocationValue& loc() { return static_cast<Outer*>(this)->get(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PCLocationHasher : public DefaultHasher<PCKey> {
|
struct PCLocationHasher : public DefaultHasher<PCKey> {
|
||||||
using ScriptPtrHasher = DefaultHasher<JSScript*>;
|
using ScriptPtrHasher = DefaultHasher<JSScript*>;
|
||||||
|
|
@ -313,15 +295,32 @@ class SavedStacks {
|
||||||
MutableHandle<LocationValue> locationp);
|
MutableHandle<LocationValue> locationp);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <typename Wrapper>
|
||||||
class RootedBase<SavedStacks::LocationValue>
|
struct WrappedPtrOperations<SavedStacks::LocationValue, Wrapper>
|
||||||
: public SavedStacks::MutableLocationValueOperations<JS::Rooted<SavedStacks::LocationValue>>
|
{
|
||||||
{};
|
JSAtom* source() const { return loc().source; }
|
||||||
|
size_t line() const { return loc().line; }
|
||||||
|
uint32_t column() const { return loc().column; }
|
||||||
|
|
||||||
template <>
|
private:
|
||||||
class MutableHandleBase<SavedStacks::LocationValue>
|
const SavedStacks::LocationValue& loc() const {
|
||||||
: public SavedStacks::MutableLocationValueOperations<JS::MutableHandle<SavedStacks::LocationValue>>
|
return static_cast<const Wrapper*>(this)->get();
|
||||||
{};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Wrapper>
|
||||||
|
struct MutableWrappedPtrOperations<SavedStacks::LocationValue, Wrapper>
|
||||||
|
: public WrappedPtrOperations<SavedStacks::LocationValue, Wrapper>
|
||||||
|
{
|
||||||
|
void setSource(JSAtom* v) { loc().source = v; }
|
||||||
|
void setLine(size_t v) { loc().line = v; }
|
||||||
|
void setColumn(uint32_t v) { loc().column = v; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SavedStacks::LocationValue& loc() {
|
||||||
|
return static_cast<Wrapper*>(this)->get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
UTF8CharsZ
|
UTF8CharsZ
|
||||||
BuildUTF8StackString(JSContext* cx, HandleObject stack);
|
BuildUTF8StackString(JSContext* cx, HandleObject stack);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
class ModuleObject;
|
class ModuleObject;
|
||||||
|
class Scope;
|
||||||
|
|
||||||
enum class BindingKind : uint8_t
|
enum class BindingKind : uint8_t
|
||||||
{
|
{
|
||||||
|
|
@ -223,6 +224,21 @@ class BindingLocation
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allow using is<T> and as<T> on Rooted<Scope*> and Handle<Scope*>.
|
||||||
|
//
|
||||||
|
template <typename Wrapper>
|
||||||
|
class WrappedPtrOperations<Scope*, Wrapper>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <class U>
|
||||||
|
JS::Handle<U*> as() const {
|
||||||
|
const Wrapper& self = *static_cast<const Wrapper*>(this);
|
||||||
|
MOZ_ASSERT_IF(self, self->template is<U>());
|
||||||
|
return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// The base class of all Scopes.
|
// The base class of all Scopes.
|
||||||
//
|
//
|
||||||
|
|
@ -1338,10 +1354,10 @@ class MOZ_STACK_CLASS ScopeIter
|
||||||
// Specializations of Rooted containers for the iterators.
|
// Specializations of Rooted containers for the iterators.
|
||||||
//
|
//
|
||||||
|
|
||||||
template <typename Outer>
|
template <typename Wrapper>
|
||||||
class BindingIterOperations
|
class WrappedPtrOperations<BindingIter, Wrapper>
|
||||||
{
|
{
|
||||||
const BindingIter& iter() const { return static_cast<const Outer*>(this)->get(); }
|
const BindingIter& iter() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool done() const { return iter().done(); }
|
bool done() const { return iter().done(); }
|
||||||
|
|
@ -1361,19 +1377,20 @@ class BindingIterOperations
|
||||||
uint32_t nextEnvironmentSlot() const { return iter().nextEnvironmentSlot(); }
|
uint32_t nextEnvironmentSlot() const { return iter().nextEnvironmentSlot(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
template <typename Wrapper>
|
||||||
class MutableBindingIterOperations : public BindingIterOperations<Outer>
|
class MutableWrappedPtrOperations<BindingIter, Wrapper>
|
||||||
|
: public WrappedPtrOperations<BindingIter, Wrapper>
|
||||||
{
|
{
|
||||||
BindingIter& iter() { return static_cast<Outer*>(this)->get(); }
|
BindingIter& iter() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void operator++(int) { iter().operator++(1); }
|
void operator++(int) { iter().operator++(1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
template <typename Wrapper>
|
||||||
class ScopeIterOperations
|
class WrappedPtrOperations<ScopeIter, Wrapper>
|
||||||
{
|
{
|
||||||
const ScopeIter& iter() const { return static_cast<const Outer*>(this)->get(); }
|
const ScopeIter& iter() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool done() const { return iter().done(); }
|
bool done() const { return iter().done(); }
|
||||||
|
|
@ -1384,69 +1401,16 @@ class ScopeIterOperations
|
||||||
bool hasSyntacticEnvironment() const { return iter().hasSyntacticEnvironment(); }
|
bool hasSyntacticEnvironment() const { return iter().hasSyntacticEnvironment(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
template <typename Wrapper>
|
||||||
class MutableScopeIterOperations : public ScopeIterOperations<Outer>
|
class MutableWrappedPtrOperations<ScopeIter, Wrapper>
|
||||||
|
: public WrappedPtrOperations<ScopeIter, Wrapper>
|
||||||
{
|
{
|
||||||
ScopeIter& iter() { return static_cast<Outer*>(this)->get(); }
|
ScopeIter& iter() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void operator++(int) { iter().operator++(1); }
|
void operator++(int) { iter().operator++(1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SPECIALIZE_ROOTING_CONTAINERS(Iter, BaseIter) \
|
|
||||||
template <> \
|
|
||||||
class RootedBase<Iter> \
|
|
||||||
: public Mutable##BaseIter##Operations<JS::Rooted<Iter>> \
|
|
||||||
{ }; \
|
|
||||||
\
|
|
||||||
template <> \
|
|
||||||
class MutableHandleBase<Iter> \
|
|
||||||
: public Mutable##BaseIter##Operations<JS::MutableHandle<Iter>> \
|
|
||||||
{ }; \
|
|
||||||
\
|
|
||||||
template <> \
|
|
||||||
class HandleBase<Iter> \
|
|
||||||
: public BaseIter##Operations<JS::Handle<Iter>> \
|
|
||||||
{ }; \
|
|
||||||
\
|
|
||||||
template <> \
|
|
||||||
class PersistentRootedBase<Iter> \
|
|
||||||
: public Mutable##BaseIter##Operations<JS::PersistentRooted<Iter>> \
|
|
||||||
{ }
|
|
||||||
|
|
||||||
SPECIALIZE_ROOTING_CONTAINERS(BindingIter, BindingIter);
|
|
||||||
SPECIALIZE_ROOTING_CONTAINERS(PositionalFormalParameterIter, BindingIter);
|
|
||||||
SPECIALIZE_ROOTING_CONTAINERS(ScopeIter, ScopeIter);
|
|
||||||
|
|
||||||
#undef SPECIALIZE_ROOTING_CONTAINERS
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allow using is<T> and as<T> on Rooted<Scope*> and Handle<Scope*>.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename Outer>
|
|
||||||
struct ScopeCastOperation
|
|
||||||
{
|
|
||||||
template <class U>
|
|
||||||
JS::Handle<U*> as() const {
|
|
||||||
const Outer& self = *static_cast<const Outer*>(this);
|
|
||||||
MOZ_ASSERT_IF(self, self->template is<U>());
|
|
||||||
return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class RootedBase<Scope*> : public ScopeCastOperation<JS::Rooted<Scope*>>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class HandleBase<Scope*> : public ScopeCastOperation<JS::Handle<Scope*>>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class MutableHandleBase<Scope*> : public ScopeCastOperation<JS::MutableHandle<Scope*>>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
|
||||||
|
|
@ -1264,9 +1264,10 @@ struct InitialShapeEntry
|
||||||
|
|
||||||
bool needsSweep() {
|
bool needsSweep() {
|
||||||
Shape* ushape = shape.unbarrieredGet();
|
Shape* ushape = shape.unbarrieredGet();
|
||||||
JSObject* protoObj = proto.proto().raw();
|
TaggedProto uproto = proto.proto().unbarrieredGet();
|
||||||
|
JSObject* protoObj = uproto.raw();
|
||||||
return (gc::IsAboutToBeFinalizedUnbarriered(&ushape) ||
|
return (gc::IsAboutToBeFinalizedUnbarriered(&ushape) ||
|
||||||
(proto.proto().isObject() && gc::IsAboutToBeFinalizedUnbarriered(&protoObj)));
|
(uproto.isObject() && gc::IsAboutToBeFinalizedUnbarriered(&protoObj)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1356,9 +1357,10 @@ struct StackShape
|
||||||
void trace(JSTracer* trc);
|
void trace(JSTracer* trc);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
template <typename Wrapper>
|
||||||
class StackShapeOperations {
|
class WrappedPtrOperations<StackShape, Wrapper>
|
||||||
const StackShape& ss() const { return static_cast<const Outer*>(this)->get(); }
|
{
|
||||||
|
const StackShape& ss() const { return static_cast<const Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool hasSlot() const { return ss().hasSlot(); }
|
bool hasSlot() const { return ss().hasSlot(); }
|
||||||
|
|
@ -1370,9 +1372,11 @@ class StackShapeOperations {
|
||||||
uint8_t attrs() const { return ss().attrs; }
|
uint8_t attrs() const { return ss().attrs; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Outer>
|
template <typename Wrapper>
|
||||||
class MutableStackShapeOperations : public StackShapeOperations<Outer> {
|
class MutableWrappedPtrOperations<StackShape, Wrapper>
|
||||||
StackShape& ss() { return static_cast<Outer*>(this)->get(); }
|
: public WrappedPtrOperations<StackShape, Wrapper>
|
||||||
|
{
|
||||||
|
StackShape& ss() { return static_cast<Wrapper*>(this)->get(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void updateGetterSetter(GetterOp rawGetter, SetterOp rawSetter) {
|
void updateGetterSetter(GetterOp rawGetter, SetterOp rawSetter) {
|
||||||
|
|
@ -1383,19 +1387,6 @@ class MutableStackShapeOperations : public StackShapeOperations<Outer> {
|
||||||
void setAttrs(uint8_t attrs) { ss().attrs = attrs; }
|
void setAttrs(uint8_t attrs) { ss().attrs = attrs; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class RootedBase<StackShape> : public MutableStackShapeOperations<JS::Rooted<StackShape>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class HandleBase<StackShape> : public StackShapeOperations<JS::Handle<StackShape>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class MutableHandleBase<StackShape>
|
|
||||||
: public MutableStackShapeOperations<JS::MutableHandle<StackShape>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
Shape::Shape(const StackShape& other, uint32_t nfixed)
|
Shape::Shape(const StackShape& other, uint32_t nfixed)
|
||||||
: base_(other.base),
|
: base_(other.base),
|
||||||
|
|
|
||||||
|
|
@ -77,11 +77,11 @@ struct InternalBarrierMethods<TaggedProto>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Outer>
|
template <class Wrapper>
|
||||||
class TaggedProtoOperations
|
class WrappedPtrOperations<TaggedProto, Wrapper>
|
||||||
{
|
{
|
||||||
const TaggedProto& value() const {
|
const TaggedProto& value() const {
|
||||||
return static_cast<const Outer*>(this)->get();
|
return static_cast<const Wrapper*>(this)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -95,18 +95,6 @@ class TaggedProtoOperations
|
||||||
uint64_t uniqueId() const { return value().uniqueId(); }
|
uint64_t uniqueId() const { return value().uniqueId(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class HandleBase<TaggedProto> : public TaggedProtoOperations<Handle<TaggedProto>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class RootedBase<TaggedProto> : public TaggedProtoOperations<Rooted<TaggedProto>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class BarrieredBaseMixins<TaggedProto> : public TaggedProtoOperations<GCPtr<TaggedProto>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
// If the TaggedProto is a JSObject pointer, convert to that type and call |f|
|
// If the TaggedProto is a JSObject pointer, convert to that type and call |f|
|
||||||
// with the pointer. If the TaggedProto is lazy, calls F::defaultValue.
|
// with the pointer. If the TaggedProto is lazy, calls F::defaultValue.
|
||||||
template <typename F, typename... Args>
|
template <typename F, typename... Args>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue