summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/Weak.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap/Weak.h')
-rw-r--r--Source/JavaScriptCore/heap/Weak.h176
1 files changed, 98 insertions, 78 deletions
diff --git a/Source/JavaScriptCore/heap/Weak.h b/Source/JavaScriptCore/heap/Weak.h
index 8291e4440..0938249b8 100644
--- a/Source/JavaScriptCore/heap/Weak.h
+++ b/Source/JavaScriptCore/heap/Weak.h
@@ -27,109 +27,129 @@
#define Weak_h
#include <wtf/Assertions.h>
-#include "Handle.h"
-#include "HandleHeap.h"
-#include "JSGlobalData.h"
#include "PassWeak.h"
+#include "WeakSetInlines.h"
namespace JSC {
-// A weakly referenced handle that becomes 0 when the value it points to is garbage collected.
-template <typename T> class Weak : public Handle<T> {
+template<typename T> class Weak : public WeakImplAccessor<Weak<T>, T> {
WTF_MAKE_NONCOPYABLE(Weak);
-
- using Handle<T>::slot;
- using Handle<T>::setSlot;
-
public:
- typedef typename Handle<T>::ExternalType ExternalType;
-
- Weak()
- : Handle<T>()
- {
- }
-
- Weak(std::nullptr_t)
- : Handle<T>()
- {
- }
-
- Weak(JSGlobalData& globalData, ExternalType externalType = ExternalType(), WeakHandleOwner* weakOwner = 0, void* context = 0)
- : Handle<T>(globalData.heap.handleHeap()->allocate())
- {
- HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
- JSValue value = HandleTypes<T>::toJSValue(externalType);
- HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
- *slot() = value;
- }
-
- enum AdoptTag { Adopt };
- template<typename U> Weak(AdoptTag, Handle<U> handle)
- : Handle<T>(handle.slot())
- {
- validateCell(get());
- }
+ friend class WeakImplAccessor<Weak<T>, T>;
+ typedef typename WeakImplAccessor<Weak<T>, T>::GetType GetType;
+
+ Weak();
+ Weak(std::nullptr_t);
+ Weak(GetType, WeakHandleOwner* = 0, void* context = 0);
enum HashTableDeletedValueTag { HashTableDeletedValue };
- bool isHashTableDeletedValue() const { return slot() == hashTableDeletedValue(); }
- Weak(HashTableDeletedValueTag)
- : Handle<T>(hashTableDeletedValue())
- {
- }
-
- template<typename U> Weak(const PassWeak<U>& other)
- : Handle<T>(other.leakHandle())
- {
- }
-
- ~Weak()
- {
- clear();
- }
-
- void swap(Weak& other)
- {
- Handle<T>::swap(other);
- }
+ bool isHashTableDeletedValue() const;
+ Weak(HashTableDeletedValueTag);
- Weak& operator=(const PassWeak<T>&);
+ template<typename U> Weak(const PassWeak<U>&);
- ExternalType get() const { return HandleTypes<T>::getFromSlot(slot()); }
-
- PassWeak<T> release() { PassWeak<T> tmp = adoptWeak<T>(slot()); setSlot(0); return tmp; }
-
- void clear()
- {
- if (!slot())
- return;
- HandleHeap::heapFor(slot())->deallocate(slot());
- setSlot(0);
- }
+ ~Weak();
+
+ void swap(Weak&);
+ Weak& operator=(const PassWeak<T>&);
- HandleSlot leakHandle()
- {
- ASSERT(HandleHeap::heapFor(slot())->hasFinalizer(slot()));
- HandleSlot result = slot();
- setSlot(0);
- return result;
- }
+ bool operator!() const;
+ // This conversion operator allows implicit conversion to bool but not to other integer types.
+ typedef JSValue (HandleBase::*UnspecifiedBoolType);
+ operator UnspecifiedBoolType*() const;
+
+ PassWeak<T> release();
+ void clear();
+
private:
- static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
+ static WeakImpl* hashTableDeletedValue();
+
+ WeakImpl* m_impl;
};
+template<typename T> inline Weak<T>::Weak()
+ : m_impl(0)
+{
+}
+
+template<typename T> inline Weak<T>::Weak(std::nullptr_t)
+ : m_impl(0)
+{
+}
+
+template<typename T> inline Weak<T>::Weak(typename Weak<T>::GetType getType, WeakHandleOwner* weakOwner, void* context)
+ : m_impl(getType ? WeakSet::allocate(getType, weakOwner, context) : 0)
+{
+}
+
+template<typename T> inline bool Weak<T>::isHashTableDeletedValue() const
+{
+ return m_impl == hashTableDeletedValue();
+}
+
+template<typename T> inline Weak<T>::Weak(typename Weak<T>::HashTableDeletedValueTag)
+ : m_impl(hashTableDeletedValue())
+{
+}
+
+template<typename T> template<typename U> inline Weak<T>::Weak(const PassWeak<U>& other)
+ : m_impl(other.leakImpl())
+{
+}
+
+template<typename T> inline Weak<T>::~Weak()
+{
+ clear();
+}
+
template<class T> inline void swap(Weak<T>& a, Weak<T>& b)
{
a.swap(b);
}
+template<typename T> inline void Weak<T>::swap(Weak& other)
+{
+ std::swap(m_impl, other.m_impl);
+}
+
template<typename T> inline Weak<T>& Weak<T>::operator=(const PassWeak<T>& o)
{
clear();
- setSlot(o.leakHandle());
+ m_impl = o.leakImpl();
return *this;
}
+template<typename T> inline bool Weak<T>::operator!() const
+{
+ return !m_impl || !m_impl->jsValue() || m_impl->state() != WeakImpl::Live;
+}
+
+template<typename T> inline Weak<T>::operator UnspecifiedBoolType*() const
+{
+ return reinterpret_cast<UnspecifiedBoolType*>(!!*this);
+}
+
+template<typename T> inline PassWeak<T> Weak<T>::release()
+{
+ PassWeak<T> tmp = adoptWeak<T>(m_impl);
+ m_impl = 0;
+ return tmp;
+}
+
+template<typename T> inline void Weak<T>::clear()
+{
+ if (!m_impl)
+ return;
+ WeakSet::deallocate(m_impl);
+ m_impl = 0;
+}
+
+template<typename T> inline WeakImpl* Weak<T>::hashTableDeletedValue()
+{
+ return reinterpret_cast<WeakImpl*>(-1);
+}
+
} // namespace JSC
namespace WTF {
@@ -151,7 +171,7 @@ template<typename T> struct HashTraits<JSC::Weak<T> > : SimpleClassHashTraits<JS
static PassOutType passOut(StorageType& value) { return value.release(); }
static PassOutType passOut(EmptyValueType) { return PassOutType(); }
- typedef typename StorageType::ExternalType PeekType;
+ typedef typename StorageType::GetType PeekType;
static PeekType peek(const StorageType& value) { return value.get(); }
static PeekType peek(EmptyValueType) { return PeekType(); }
};