#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
#include "third_party/blink/renderer/platform/wtf/vector_traits.h"
#include "v8/include/cppgc/cross-thread-persistent.h"
#include "v8/include/cppgc/persistent.h"
#include "v8/include/cppgc/source-location.h"
#if BUILDFLAG(VERBOSE_PERSISTENT)
#define PERSISTENT_LOCATION_FROM_HERE blink::PersistentLocation::Current()
#else
#define PERSISTENT_LOCATION_FROM_HERE blink::PersistentLocation()
#endif
namespace blink {
template <typename T>
using Persistent = cppgc::Persistent<T>;
template <typename T>
using WeakPersistent = cppgc::WeakPersistent<T>;
using PersistentLocation = cppgc::SourceLocation;
template <typename T>
Persistent<T> WrapPersistent(
T* value,
const PersistentLocation& loc = PERSISTENT_LOCATION_FROM_HERE) {
return Persistent<T>(value, loc);
}
template <typename T>
WeakPersistent<T> WrapWeakPersistent(
T* value,
const PersistentLocation& loc = PERSISTENT_LOCATION_FROM_HERE) {
return WeakPersistent<T>(value, loc);
}
template <typename U, typename T, typename weakness>
cppgc::internal::BasicPersistent<U, weakness> DownCast(
const cppgc::internal::BasicPersistent<T, weakness>& p) {
return p.template To<U>();
}
template <typename U, typename T, typename weakness>
cppgc::internal::BasicCrossThreadPersistent<U, weakness> DownCast(
const cppgc::internal::BasicCrossThreadPersistent<T, weakness>& p) {
return p.template To<U>();
}
template <typename T>
requires(IsGarbageCollectedTypeV<T>)
Persistent<T> WrapPersistentIfNeeded(T* value) {
return Persistent<T>(value);
}
template <typename T>
T& WrapPersistentIfNeeded(T& value) {
return value;
}
template <typename T>
struct PersistentVectorTraitsBase : VectorTraitsBase<T> {
STATIC_ONLY(PersistentVectorTraitsBase);
static const bool kCanInitializeWithMemset = true;
};
template <typename T>
struct VectorTraits<Persistent<T>> : PersistentVectorTraitsBase<Persistent<T>> {
};
template <typename T>
struct VectorTraits<WeakPersistent<T>>
: PersistentVectorTraitsBase<WeakPersistent<T>> {};
template <typename T, typename PersistentType>
struct BasePersistentHashTraits : SimpleClassHashTraits<PersistentType> {
template <typename U>
static unsigned GetHash(const U& key) {
return blink::GetHash<T*>(key);
}
template <typename U, typename V>
static bool Equal(const U& a, const V& b) {
return a == b;
}
using PeekInType = T*;
using IteratorGetType = PersistentType*;
using IteratorConstGetType = const PersistentType*;
using IteratorReferenceType = PersistentType&;
using IteratorConstReferenceType = const PersistentType&;
using PeekOutType = T*;
template <typename U>
static void Store(const U& value, PersistentType& storage) {
storage = value;
}
static PeekOutType Peek(const PersistentType& value) { return value; }
static void ConstructDeletedValue(PersistentType& slot) {
new (&slot) PersistentType(cppgc::kSentinelPointer);
}
static bool IsDeletedValue(const PersistentType& value) {
return value.Get() == cppgc::kSentinelPointer;
}
};
template <typename T>
struct HashTraits<blink::Persistent<T>>
: BasePersistentHashTraits<T, blink::Persistent<T>> {};
template <typename T>
struct HashTraits<blink::WeakPersistent<T>>
: BasePersistentHashTraits<T, blink::WeakPersistent<T>> {};
}
namespace base {
template <typename T>
struct IsWeakReceiver;
template <typename T>
struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {};
template <typename>
struct MaybeValidTraits;
template <typename T>
struct MaybeValidTraits<blink::WeakPersistent<T>> {
static bool MaybeValid(const blink::WeakPersistent<T>& p) { return true; }
};
}
#endif