Changeset 113141 in webkit for trunk/Source/JavaScriptCore/heap/PassWeak.h
- Timestamp:
- Apr 3, 2012, 10:28:13 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/heap/PassWeak.h
r110033 r113141 27 27 #define PassWeak_h 28 28 29 #include "JSCell.h" 29 30 #include <wtf/Assertions.h> 30 #include "Handle.h"31 31 #include <wtf/NullPtr.h> 32 32 #include <wtf/TypeTraits.h> … … 36 36 template<typename T> class Weak; 37 37 template<typename T> class PassWeak; 38 template<typename T> PassWeak<T> adoptWeak(HandleSlot); 39 40 template<typename T> class PassWeak : public Handle<T> { 41 using Handle<T>::slot; 42 using Handle<T>::setSlot; 43 38 template<typename T> PassWeak<T> adoptWeak(WeakImpl*); 39 40 template<typename Base, typename T> class WeakImplAccessor { 44 41 public: 45 typedef typename Handle<T>::ExternalType ExternalType; 46 47 PassWeak() : Handle<T>() { } 48 PassWeak(std::nullptr_t) : Handle<T>() { } 49 50 PassWeak(JSGlobalData& globalData, ExternalType externalType = ExternalType(), WeakHandleOwner* weakOwner = 0, void* context = 0) 51 : Handle<T>(globalData.heap.handleHeap()->allocate()) 52 { 53 HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context); 54 JSValue value = HandleTypes<T>::toJSValue(externalType); 55 HandleHeap::heapFor(slot())->writeBarrier(slot(), value); 56 *slot() = value; 57 } 42 typedef T* GetType; 43 44 T* operator->() const; 45 T& operator*() const; 46 GetType get() const; 47 48 #if !ASSERT_DISABLED 49 bool was(GetType) const; 50 #endif 51 }; 52 53 template<typename Base> class WeakImplAccessor<Base, Unknown> { 54 public: 55 typedef JSValue GetType; 56 57 const JSValue* operator->() const; 58 const JSValue& operator*() const; 59 GetType get() const; 60 }; 61 62 template<typename T> class PassWeak : public WeakImplAccessor<PassWeak<T>, T> { 63 public: 64 friend class WeakImplAccessor<PassWeak<T>, T>; 65 typedef typename WeakImplAccessor<PassWeak<T>, T>::GetType GetType; 66 67 PassWeak(); 68 PassWeak(std::nullptr_t); 69 PassWeak(JSGlobalData&, GetType = GetType(), WeakHandleOwner* = 0, void* context = 0); 58 70 59 71 // It somewhat breaks the type system to allow transfer of ownership out of 60 72 // a const PassWeak. However, it makes it much easier to work with PassWeak 61 73 // temporaries, and we don't have a need to use real const PassWeaks anyway. 62 PassWeak(const PassWeak& o) : Handle<T>(o.leakHandle()) { } 63 template<typename U> PassWeak(const PassWeak<U>& o) : Handle<T>(o.leakHandle()) { } 64 65 ~PassWeak() 66 { 67 if (!slot()) 68 return; 69 HandleHeap::heapFor(slot())->deallocate(slot()); 70 setSlot(0); 71 } 72 73 ExternalType get() const { return HandleTypes<T>::getFromSlot(slot()); } 74 75 HandleSlot leakHandle() const WARN_UNUSED_RETURN; 74 PassWeak(const PassWeak&); 75 template<typename U> PassWeak(const PassWeak<U>&); 76 77 ~PassWeak(); 78 79 bool operator!() const; 80 81 // This conversion operator allows implicit conversion to bool but not to other integer types. 82 typedef JSValue (PassWeak::*UnspecifiedBoolType); 83 operator UnspecifiedBoolType*() const; 84 85 WeakImpl* leakImpl() const WARN_UNUSED_RETURN; 76 86 77 87 private: 78 friend PassWeak adoptWeak<T>(HandleSlot); 79 80 explicit PassWeak(HandleSlot slot) : Handle<T>(slot) { } 88 friend PassWeak adoptWeak<T>(WeakImpl*); 89 explicit PassWeak(WeakImpl*); 90 91 WeakImpl* m_impl; 81 92 }; 82 93 83 template<typename T> inline HandleSlot PassWeak<T>::leakHandle() const 84 { 85 HandleSlot slot = this->slot(); 86 const_cast<PassWeak<T>*>(this)->setSlot(0); 87 return slot; 88 } 89 90 template<typename T> PassWeak<T> adoptWeak(HandleSlot slot) 91 { 92 return PassWeak<T>(slot); 94 template<typename Base, typename T> inline T* WeakImplAccessor<Base, T>::operator->() const 95 { 96 ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live); 97 return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell()); 98 } 99 100 template<typename Base, typename T> inline T& WeakImplAccessor<Base, T>::operator*() const 101 { 102 ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live); 103 return *jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell()); 104 } 105 106 template<typename Base, typename T> inline typename WeakImplAccessor<Base, T>::GetType WeakImplAccessor<Base, T>::get() const 107 { 108 if (!static_cast<const Base*>(this)->m_impl || static_cast<const Base*>(this)->m_impl->state() != WeakImpl::Live) 109 return GetType(); 110 return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell()); 111 } 112 113 #if !ASSERT_DISABLED 114 template<typename Base, typename T> inline bool WeakImplAccessor<Base, T>::was(typename WeakImplAccessor<Base, T>::GetType other) const 115 { 116 return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell()) == other; 117 } 118 #endif 119 120 template<typename Base> inline const JSValue* WeakImplAccessor<Base, Unknown>::operator->() const 121 { 122 ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live); 123 return &static_cast<const Base*>(this)->m_impl->jsValue(); 124 } 125 126 template<typename Base> inline const JSValue& WeakImplAccessor<Base, Unknown>::operator*() const 127 { 128 ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live); 129 return static_cast<const Base*>(this)->m_impl->jsValue(); 130 } 131 132 template<typename Base> inline typename WeakImplAccessor<Base, Unknown>::GetType WeakImplAccessor<Base, Unknown>::get() const 133 { 134 if (!static_cast<const Base*>(this)->m_impl || static_cast<const Base*>(this)->m_impl->state() != WeakImpl::Live) 135 return GetType(); 136 return static_cast<const Base*>(this)->m_impl->jsValue(); 137 } 138 139 template<typename T> inline PassWeak<T>::PassWeak() 140 : m_impl(0) 141 { 142 } 143 144 template<typename T> inline PassWeak<T>::PassWeak(std::nullptr_t) 145 : m_impl(0) 146 { 147 } 148 149 template<typename T> inline PassWeak<T>::PassWeak(JSGlobalData& globalData, typename PassWeak<T>::GetType getType, WeakHandleOwner* weakOwner, void* context) 150 : m_impl(globalData.heap.weakHeap()->allocate(getType, weakOwner, context)) 151 { 152 } 153 154 template<typename T> inline PassWeak<T>::PassWeak(const PassWeak& o) 155 : m_impl(o.leakImpl()) 156 { 157 } 158 159 template<typename T> template<typename U> inline PassWeak<T>::PassWeak(const PassWeak<U>& o) 160 : m_impl(o.leakImpl()) 161 { 162 } 163 164 template<typename T> inline PassWeak<T>::~PassWeak() 165 { 166 if (!m_impl) 167 return; 168 WeakHeap::deallocate(m_impl); 169 } 170 171 template<typename T> inline bool PassWeak<T>::operator!() const 172 { 173 return !m_impl || m_impl->state() != WeakImpl::Live || !m_impl->jsValue(); 174 } 175 176 template<typename T> inline PassWeak<T>::operator UnspecifiedBoolType*() const 177 { 178 return reinterpret_cast<UnspecifiedBoolType*>(!!*this); 179 } 180 181 template<typename T> inline PassWeak<T>::PassWeak(WeakImpl* impl) 182 : m_impl(impl) 183 { 184 } 185 186 template<typename T> inline WeakImpl* PassWeak<T>::leakImpl() const 187 { 188 WeakImpl* tmp = 0; 189 std::swap(tmp, const_cast<WeakImpl*&>(m_impl)); 190 return tmp; 191 } 192 193 template<typename T> PassWeak<T> inline adoptWeak(WeakImpl* impl) 194 { 195 return PassWeak<T>(impl); 93 196 } 94 197
Note:
See TracChangeset
for help on using the changeset viewer.