Changeset 226015 in webkit
- Timestamp:
- Dec 17, 2017, 3:22:18 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r225998 r226015 1 2017-12-17 Mark Lam <mark.lam@apple.com> 2 3 Enhance Ref and RefPtr to be able to work with smart pointers. 4 https://bugs.webkit.org/show_bug.cgi?id=180762 5 <rdar://problem/36027122> 6 7 Reviewed by JF Bastien and Darin Adler. 8 9 This is so we can use them with ConstExprPoisoned pointers to make PoisonedRef 10 and PoisonedRefPtr. 11 12 * WTF.xcodeproj/project.pbxproj: 13 * wtf/CMakeLists.txt: 14 * wtf/DumbPtrTraits.h: Added. 15 (WTF::DumbPtrTraits::exchange): 16 (WTF::DumbPtrTraits::swap): 17 (WTF::DumbPtrTraits::unwrap): 18 * wtf/Forward.h: 19 * wtf/Poisoned.h: 20 (WTF::ConstExprPoisonedPtrTraits::exchange): 21 (WTF::ConstExprPoisonedPtrTraits::swap): 22 (WTF::ConstExprPoisonedPtrTraits::unwrap): 23 * wtf/Ref.h: 24 (WTF::Ref::~Ref): 25 (WTF::Ref::Ref): 26 (WTF::Ref::ptrAllowingHashTableEmptyValue const): 27 (WTF::Ref::ptrAllowingHashTableEmptyValue): 28 (WTF::Ref::operator-> const): 29 (WTF::Ref::get const): 30 (WTF::Ref::operator T& const): 31 (WTF::=): 32 (WTF::U>::swap): 33 (WTF::swap): 34 (WTF::U>::replace): 35 (WTF::static_reference_cast): 36 (WTF::adoptRef): 37 (WTF::is): 38 (WTF::Ref<T>::swap): Deleted. 39 (WTF::Ref<T>::replace): Deleted. 40 (WTF::GetPtrHelper<Ref<T>>::getPtr): Deleted. 41 * wtf/RefPtr.cpp: Added. 42 * wtf/RefPtr.h: 43 (WTF::RefPtr::RefPtr): 44 (WTF::RefPtr::~RefPtr): 45 (WTF::RefPtr::get const): 46 (WTF::RefPtr::operator* const): 47 (WTF::RefPtr::operator-> const): 48 (WTF::U>::RefPtr): 49 (WTF::U>::leakRef): 50 (WTF::=): 51 (WTF::U>::swap): 52 (WTF::swap): 53 (WTF::operator==): 54 (WTF::operator!=): 55 (WTF::static_pointer_cast): 56 (WTF::adoptRef): 57 (WTF::is): 58 (WTF::RefPtr<T>::RefPtr): Deleted. 59 (WTF::RefPtr<T>::leakRef): Deleted. 60 (WTF::RefPtr<T>::swap): Deleted. 61 1 62 2017-12-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 63 -
trunk/Source/WTF/WTF.xcodeproj/project.pbxproj
r225832 r226015 151 151 E4A0AD391A96245500536DF6 /* WorkQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD371A96245500536DF6 /* WorkQueue.cpp */; }; 152 152 E4A0AD3D1A96253C00536DF6 /* WorkQueueCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD3C1A96253C00536DF6 /* WorkQueueCocoa.cpp */; }; 153 FE05FAFF1FE5007500093230 /* RefPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAFE1FE5007500093230 /* RefPtr.cpp */; }; 153 154 FE85416E1FBE285D008DA5DA /* Poisoned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE85416C1FBE285B008DA5DA /* Poisoned.cpp */; }; 154 155 FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDACD3B1630F83F00C69634 /* StackStats.cpp */; }; … … 617 618 EF7D6CD59D8642A8A0DA86AD /* StackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackTrace.h; sourceTree = "<group>"; }; 618 619 F72BBDB107FA424886178B9E /* SymbolImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolImpl.cpp; sourceTree = "<group>"; }; 620 FE05FAE61FDB214300093230 /* DumbPtrTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumbPtrTraits.h; sourceTree = "<group>"; }; 621 FE05FAFE1FE5007500093230 /* RefPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefPtr.cpp; sourceTree = "<group>"; }; 619 622 FE8225301B2A1E5B00BA68FD /* NakedPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NakedPtr.h; sourceTree = "<group>"; }; 620 623 FE85416C1FBE285B008DA5DA /* Poisoned.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Poisoned.cpp; sourceTree = "<group>"; }; … … 849 852 0F4570421BE5B58F0062A629 /* Dominators.h */, 850 853 A8A47280151A825A004123FF /* DoublyLinkedList.h */, 854 FE05FAE61FDB214300093230 /* DumbPtrTraits.h */, 851 855 A8A47297151A825A004123FF /* dtoa.cpp */, 852 856 A8A47298151A825A004123FF /* dtoa.h */, … … 1005 1009 A8A47302151A825B004123FF /* RefCountedLeakCounter.h */, 1006 1010 86F46F5F1A2840EE00CCBF22 /* RefCounter.h */, 1011 FE05FAFE1FE5007500093230 /* RefPtr.cpp */, 1007 1012 A8A47303151A825B004123FF /* RefPtr.h */, 1008 1013 A8A47305151A825B004123FF /* RetainPtr.h */, … … 1412 1417 A8A47460151A825B004123FF /* CollatorDefault.cpp in Sources */, 1413 1418 A8A47463151A825B004123FF /* CollatorICU.cpp in Sources */, 1419 FE05FAFF1FE5007500093230 /* RefPtr.cpp in Sources */, 1414 1420 0F8F2B92172E0103007DBDA5 /* CompilationThread.cpp in Sources */, 1415 1421 E38C41281EB4E0680042957D /* CPUTime.cpp in Sources */, -
trunk/Source/WTF/wtf/CMakeLists.txt
r225832 r226015 38 38 DisallowCType.h 39 39 DoublyLinkedList.h 40 DumbPtrTraits.h 40 41 FastMalloc.h 41 42 FastTLS.h … … 269 270 ReadWriteLock.cpp 270 271 RefCountedLeakCounter.cpp 272 RefPtr.cpp 271 273 RunLoop.cpp 272 274 SHA1.cpp -
trunk/Source/WTF/wtf/Forward.h
r225824 r226015 49 49 50 50 template<typename> class CompletionHandler; 51 template<typename T> struct DumbPtrTraits; 51 52 template<typename> class Function; 52 53 template<typename> class LazyNeverDestroyed; 53 54 template<typename> class NeverDestroyed; 54 55 template<typename> class OptionSet; 55 template<typename > class Ref;56 template<typename > class RefPtr;56 template<typename T, typename = DumbPtrTraits<T>> class Ref; 57 template<typename T, typename = DumbPtrTraits<T>> class RefPtr; 57 58 template<typename> class StringBuffer; 58 59 template<typename, typename = void> class StringTypeAdapter; -
trunk/Source/WTF/wtf/Poisoned.h
r225857 r226015 229 229 using ConstExprPoisoned = PoisonedImpl<uintptr_t, makePoison(key), T>; 230 230 231 template<uint32_t key, typename T> 232 struct ConstExprPoisonedPtrTraits { 233 using StorageType = ConstExprPoisoned<key, T*>; 234 235 template<class U> static ALWAYS_INLINE T* exchange(StorageType& ptr, U&& newValue) { return ptr.exchange(newValue); } 236 237 template<typename K1, K1 k1, typename T1, typename K2, K2 k2, typename T2> 238 static ALWAYS_INLINE void swap(PoisonedImpl<K1, k1, T1>& a, PoisonedImpl<K2, k2, T2>& b) { a.swap(b); } 239 240 static ALWAYS_INLINE T* unwrap(const StorageType& ptr) { return ptr.unpoisoned(); } 241 }; 242 231 243 } // namespace WTF 232 244 -
trunk/Source/WTF/wtf/Ref.h
r218594 r226015 1 1 /* 2 * Copyright (C) 2013-201 4Apple Inc. All rights reserved.2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include <wtf/Assertions.h> 30 #include <wtf/DumbPtrTraits.h> 31 #include <wtf/Forward.h> 30 32 #include <wtf/GetPtr.h> 31 33 #include <wtf/StdLibExtras.h> … … 42 44 inline void adopted(const void*) { } 43 45 44 template<typename T> class Ref; 45 template<typename T> Ref<T> adoptRef(T&); 46 47 template<typename T> class Ref { 46 template<typename T, typename PtrTraits> class Ref; 47 template<typename T, typename PtrTraits = DumbPtrTraits<T>> Ref<T, PtrTraits> adoptRef(T&); 48 49 template<typename T, typename PtrTraits> 50 class Ref { 48 51 public: 49 52 static constexpr bool isRef = true; … … 56 59 #endif 57 60 if (m_ptr) 58 m_ptr->deref();61 PtrTraits::unwrap(m_ptr)->deref(); 59 62 } 60 63 … … 62 65 : m_ptr(&object) 63 66 { 64 m_ptr->ref();67 object.ref(); 65 68 } 66 69 67 70 // Use copyRef() instead. 68 71 Ref(const Ref& other) = delete; 69 template<typename U> Ref(const Ref<U>& other) = delete;72 template<typename X, typename Y> Ref(const Ref<X, Y>& other) = delete; 70 73 71 74 Ref(Ref&& other) … … 75 78 } 76 79 77 template<typename U>78 Ref(Ref< U>&& other)80 template<typename X, typename Y> 81 Ref(Ref<X, Y>&& other) 79 82 : m_ptr(&other.leakRef()) 80 83 { … … 84 87 Ref& operator=(T&); 85 88 Ref& operator=(Ref&&); 86 template<typename U> Ref& operator=(Ref<U>&&);89 template<typename X, typename Y> Ref& operator=(Ref<X, Y>&&); 87 90 88 91 // Use copyRef() and the move assignment operators instead. 89 92 Ref& operator=(const Ref&) = delete; 90 template<typename U> Ref& operator=(const Ref<U>&) = delete;91 92 void swap(Ref&);93 template<typename X, typename Y> Ref& operator=(const Ref<X, Y>&) = delete; 94 95 template<typename X, typename Y> void swap(Ref<X, Y>&); 93 96 94 97 // Hash table deleted values, which are only constructed and never copied or destroyed. … … 101 104 static T* hashTableEmptyValue() { return nullptr; } 102 105 103 const T* ptrAllowingHashTableEmptyValue() const { ASSERT(m_ptr || isHashTableEmptyValue()); return m_ptr; }104 T* ptrAllowingHashTableEmptyValue() { ASSERT(m_ptr || isHashTableEmptyValue()); return m_ptr; }106 const T* ptrAllowingHashTableEmptyValue() const { ASSERT(m_ptr || isHashTableEmptyValue()); return PtrTraits::unwrap(m_ptr); } 107 T* ptrAllowingHashTableEmptyValue() { ASSERT(m_ptr || isHashTableEmptyValue()); return PtrTraits::unwrap(m_ptr); } 105 108 106 109 void assignToHashTableEmptyValue(Ref&& reference) … … 111 114 } 112 115 113 T* operator->() const { ASSERT(m_ptr); return m_ptr; }114 T* ptr() const RETURNS_NONNULL { ASSERT(m_ptr); return m_ptr; }115 T& get() const { ASSERT(m_ptr); return * m_ptr; }116 operator T&() const { ASSERT(m_ptr); return * m_ptr; }116 T* operator->() const { ASSERT(m_ptr); return PtrTraits::unwrap(m_ptr); } 117 T* ptr() const RETURNS_NONNULL { ASSERT(m_ptr); return PtrTraits::unwrap(m_ptr); } 118 T& get() const { ASSERT(m_ptr); return *PtrTraits::unwrap(m_ptr); } 119 operator T&() const { ASSERT(m_ptr); return *PtrTraits::unwrap(m_ptr); } 117 120 bool operator!() const { ASSERT(m_ptr); return !*m_ptr; } 118 121 119 template<typename U> Ref<T> replace(Ref<U>&&) WARN_UNUSED_RETURN;122 template<typename X, typename Y> Ref<T, PtrTraits> replace(Ref<X, Y>&&) WARN_UNUSED_RETURN; 120 123 121 124 #if COMPILER_SUPPORTS(CXX_REFERENCE_QUALIFIED_FUNCTIONS) … … 130 133 ASSERT(m_ptr); 131 134 132 T& result = * std::exchange(m_ptr, nullptr);135 T& result = *PtrTraits::exchange(m_ptr, nullptr); 133 136 #if ASAN_ENABLED 134 137 __asan_poison_memory_region(this, sizeof(*this)); … … 139 142 private: 140 143 friend Ref adoptRef<T>(T&); 144 template<typename X, typename Y> friend class Ref; 141 145 142 146 enum AdoptTag { Adopt }; … … 146 150 } 147 151 148 T*m_ptr;152 typename PtrTraits::StorageType m_ptr; 149 153 }; 150 154 151 template<typename T> void swap(Ref<T>&, Ref<T>&); 152 template<typename T> Ref<T> adoptRef(T&); 155 template<typename T, typename U> Ref<T, U> adoptRef(T&); 153 156 template<typename T> Ref<T> makeRef(T&); 154 157 155 template<typename T> inline Ref<T>& Ref<T>::operator=(T& reference) 158 template<typename T, typename U> 159 inline Ref<T, U>& Ref<T, U>::operator=(T& reference) 156 160 { 157 161 Ref copiedReference = reference; … … 160 164 } 161 165 162 template<typename T> inline Ref<T>& Ref<T>::operator=(Ref&& reference) 166 template<typename T, typename U> 167 inline Ref<T, U>& Ref<T, U>::operator=(Ref&& reference) 163 168 { 164 169 Ref movedReference = WTFMove(reference); … … 167 172 } 168 173 169 template<typename T> template<typename U> inline Ref<T>& Ref<T>::operator=(Ref<U>&& reference) 174 template<typename T, typename U> 175 template<typename X, typename Y> 176 inline Ref<T, U>& Ref<T, U>::operator=(Ref<X, Y>&& reference) 170 177 { 171 178 Ref movedReference = WTFMove(reference); … … 174 181 } 175 182 176 template<typename T> inline void Ref<T>::swap(Ref& other) 177 { 178 std::swap(m_ptr, other.m_ptr); 179 } 180 181 template<typename T> inline void swap(Ref<T>& a, Ref<T>& b) 183 template<typename T, typename U> 184 template<typename X, typename Y> 185 inline void Ref<T, U>::swap(Ref<X, Y>& other) 186 { 187 U::swap(m_ptr, other.m_ptr); 188 } 189 190 template<typename T, typename U, typename X, typename Y, typename = std::enable_if_t<!std::is_same<U, DumbPtrTraits<T>>::value || !std::is_same<Y, DumbPtrTraits<X>>::value>> 191 inline void swap(Ref<T, U>& a, Ref<X, Y>& b) 182 192 { 183 193 a.swap(b); 184 194 } 185 195 186 template<typename T> template<typename U> inline Ref<T> Ref<T>::replace(Ref<U>&& reference) 196 template<typename T, typename U> 197 template<typename X, typename Y> 198 inline Ref<T, U> Ref<T, U>::replace(Ref<X, Y>&& reference) 187 199 { 188 200 auto oldReference = adoptRef(*m_ptr); … … 191 203 } 192 204 193 template<typename T, typename U> inline Ref<T> static_reference_cast(Ref<U>& reference) 194 { 195 return Ref<T>(static_cast<T&>(reference.get())); 196 } 197 198 template<typename T, typename U> inline Ref<T> static_reference_cast(Ref<U>&& reference) 205 template<typename T, typename U = DumbPtrTraits<T>, typename X, typename Y> 206 inline Ref<T, U> static_reference_cast(Ref<X, Y>& reference) 207 { 208 return Ref<T, U>(static_cast<T&>(reference.get())); 209 } 210 211 template<typename T, typename U = DumbPtrTraits<T>, typename X, typename Y> 212 inline Ref<T, U> static_reference_cast(Ref<X, Y>&& reference) 199 213 { 200 214 return adoptRef(static_cast<T&>(reference.leakRef())); 201 215 } 202 216 203 template<typename T, typename U> inline Ref<T> static_reference_cast(const Ref<U>& reference) 204 { 205 return Ref<T>(static_cast<T&>(reference.copyRef().get())); 206 } 207 208 template <typename T> 209 struct GetPtrHelper<Ref<T>> { 217 template<typename T, typename U = DumbPtrTraits<T>, typename X, typename Y> 218 inline Ref<T, U> static_reference_cast(const Ref<X, Y>& reference) 219 { 220 return Ref<T, U>(static_cast<T&>(reference.copyRef().get())); 221 } 222 223 template <typename T, typename U> 224 struct GetPtrHelper<Ref<T, U>> { 210 225 typedef T* PtrType; 211 static T* getPtr(const Ref<T >& p) { return const_cast<T*>(p.ptr()); }226 static T* getPtr(const Ref<T, U>& p) { return const_cast<T*>(p.ptr()); } 212 227 }; 213 228 214 template <typename T >215 struct IsSmartPtr<Ref<T >> {229 template <typename T, typename U> 230 struct IsSmartPtr<Ref<T, U>> { 216 231 static const bool value = true; 217 232 }; 218 233 219 template<typename T >220 inline Ref<T > adoptRef(T& reference)234 template<typename T, typename U> 235 inline Ref<T, U> adoptRef(T& reference) 221 236 { 222 237 adopted(&reference); 223 return Ref<T >(reference, Ref<T>::Adopt);238 return Ref<T, U>(reference, Ref<T, U>::Adopt); 224 239 } 225 240 … … 230 245 } 231 246 232 template<typename ExpectedType, typename ArgType> inline bool is(Ref<ArgType>& source) 247 template<typename ExpectedType, typename ArgType, typename PtrTraits> 248 inline bool is(Ref<ArgType, PtrTraits>& source) 233 249 { 234 250 return is<ExpectedType>(source.get()); 235 251 } 236 252 237 template<typename ExpectedType, typename ArgType> inline bool is(const Ref<ArgType>& source) 253 template<typename ExpectedType, typename ArgType, typename PtrTraits> 254 inline bool is(const Ref<ArgType, PtrTraits>& source) 238 255 { 239 256 return is<ExpectedType>(source.get()); 240 257 } 241 258 259 template<uint32_t key, typename T> struct ConstExprPoisonedPtrTraits; 260 261 template<uint32_t key, typename T> 262 using PoisonedRef = Ref<T, ConstExprPoisonedPtrTraits<key, T>>; 263 242 264 } // namespace WTF 243 265 266 using WTF::PoisonedRef; 244 267 using WTF::Ref; 245 268 using WTF::adoptRef; -
trunk/Source/WTF/wtf/RefPtr.h
r224320 r226015 31 31 namespace WTF { 32 32 33 template<typename T > class RefPtr;34 template<typename T > RefPtr<T> adoptRef(T*);33 template<typename T, typename PtrTraits> class RefPtr; 34 template<typename T, typename PtrTraits = DumbPtrTraits<T>> RefPtr<T, PtrTraits> adoptRef(T*); 35 35 36 36 template<typename T> ALWAYS_INLINE void refIfNotNull(T* ptr) … … 46 46 } 47 47 48 template<typename T> class RefPtr { 48 template<typename T, typename PtrTraits> 49 class RefPtr { 49 50 WTF_MAKE_FAST_ALLOCATED; 50 51 public: … … 56 57 ALWAYS_INLINE constexpr RefPtr() : m_ptr(nullptr) { } 57 58 ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } 58 ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull( m_ptr); }59 template<typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { refIfNotNull(m_ptr); }59 ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(PtrTraits::unwrap(m_ptr)); } 60 template<typename X, typename Y> RefPtr(const RefPtr<X, Y>& o) : m_ptr(o.get()) { refIfNotNull(PtrTraits::unwrap(m_ptr)); } 60 61 61 62 ALWAYS_INLINE RefPtr(RefPtr&& o) : m_ptr(o.leakRef()) { } 62 template<typename U> RefPtr(RefPtr<U>&& o) : m_ptr(o.leakRef()) { }63 template<typename U> RefPtr(Ref<U>&&);63 template<typename X, typename Y> RefPtr(RefPtr<X, Y>&& o) : m_ptr(o.leakRef()) { } 64 template<typename X, typename Y> RefPtr(Ref<X, Y>&&); 64 65 65 66 // Hash table deleted values, which are only constructed and never copied or destroyed. … … 67 68 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } 68 69 69 ALWAYS_INLINE ~RefPtr() { derefIfNotNull( std::exchange(m_ptr, nullptr)); }70 71 T* get() const { return m_ptr; }70 ALWAYS_INLINE ~RefPtr() { derefIfNotNull(PtrTraits::exchange(m_ptr, nullptr)); } 71 72 T* get() const { return PtrTraits::unwrap(m_ptr); } 72 73 73 74 Ref<T> releaseNonNull() { ASSERT(m_ptr); Ref<T> tmp(adoptRef(*m_ptr)); m_ptr = nullptr; return tmp; } … … 76 77 T* leakRef() WARN_UNUSED_RETURN; 77 78 78 T& operator*() const { ASSERT(m_ptr); return * m_ptr; }79 ALWAYS_INLINE T* operator->() const { return m_ptr; }79 T& operator*() const { ASSERT(m_ptr); return *PtrTraits::unwrap(m_ptr); } 80 ALWAYS_INLINE T* operator->() const { return PtrTraits::unwrap(m_ptr); } 80 81 81 82 bool operator!() const { return !m_ptr; } … … 90 91 RefPtr& operator=(T*); 91 92 RefPtr& operator=(std::nullptr_t); 92 template<typename U> RefPtr& operator=(const RefPtr<U>&);93 template<typename X, typename Y> RefPtr& operator=(const RefPtr<X, Y>&); 93 94 RefPtr& operator=(RefPtr&&); 94 template<typename U> RefPtr& operator=(RefPtr<U>&&);95 template<typename U> RefPtr& operator=(Ref<U>&&);96 97 void swap(RefPtr&);95 template<typename X, typename Y> RefPtr& operator=(RefPtr<X, Y>&&); 96 template<typename X> RefPtr& operator=(Ref<X>&&); 97 98 template<typename X, typename Y> void swap(RefPtr<X, Y>&); 98 99 99 100 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } … … 107 108 108 109 private: 109 friend RefPtr adoptRef<T>(T*); 110 friend RefPtr adoptRef<T, PtrTraits>(T*); 111 template<typename X, typename Y> friend class RefPtr; 110 112 111 113 enum AdoptTag { Adopt }; 112 114 RefPtr(T* ptr, AdoptTag) : m_ptr(ptr) { } 113 115 114 T*m_ptr;116 typename PtrTraits::StorageType m_ptr; 115 117 }; 116 118 117 template<typename T> template<typename U> inline RefPtr<T>::RefPtr(Ref<U>&& reference) 119 template<typename T, typename U> 120 template<typename X, typename Y> 121 inline RefPtr<T, U>::RefPtr(Ref<X, Y>&& reference) 118 122 : m_ptr(&reference.leakRef()) 119 123 { 120 124 } 121 125 122 template<typename T> 123 inline T* RefPtr<T>::leakRef() 124 { 125 return std::exchange(m_ptr, nullptr); 126 } 127 128 template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr& o) 126 template<typename T, typename U> 127 inline T* RefPtr<T, U>::leakRef() 128 { 129 return U::exchange(m_ptr, nullptr); 130 } 131 132 template<typename T, typename U> 133 inline RefPtr<T, U>& RefPtr<T, U>::operator=(const RefPtr& o) 129 134 { 130 135 RefPtr ptr = o; … … 133 138 } 134 139 135 template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) 140 template<typename T, typename U> 141 template<typename X, typename Y> 142 inline RefPtr<T, U>& RefPtr<T, U>::operator=(const RefPtr<X, Y>& o) 136 143 { 137 144 RefPtr ptr = o; … … 140 147 } 141 148 142 template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) 149 template<typename T, typename U> 150 inline RefPtr<T, U>& RefPtr<T, U>::operator=(T* optr) 143 151 { 144 152 RefPtr ptr = optr; … … 147 155 } 148 156 149 template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(std::nullptr_t) 150 { 151 derefIfNotNull(std::exchange(m_ptr, nullptr)); 152 return *this; 153 } 154 155 template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(RefPtr&& o) 157 template<typename T, typename U> 158 inline RefPtr<T, U>& RefPtr<T, U>::operator=(std::nullptr_t) 159 { 160 derefIfNotNull(U::exchange(m_ptr, nullptr)); 161 return *this; 162 } 163 164 template<typename T, typename U> 165 inline RefPtr<T, U>& RefPtr<T, U>::operator=(RefPtr&& o) 156 166 { 157 167 RefPtr ptr = WTFMove(o); … … 160 170 } 161 171 162 template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(RefPtr<U>&& o) 172 template<typename T, typename U> 173 template<typename X, typename Y> 174 inline RefPtr<T, U>& RefPtr<T, U>::operator=(RefPtr<X, Y>&& o) 163 175 { 164 176 RefPtr ptr = WTFMove(o); … … 167 179 } 168 180 169 template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(Ref<U>&& reference) 181 template<typename T, typename V> 182 template<typename U> 183 inline RefPtr<T, V>& RefPtr<T, V>::operator=(Ref<U>&& reference) 170 184 { 171 185 RefPtr ptr = WTFMove(reference); … … 174 188 } 175 189 176 template<class T> inline void RefPtr<T>::swap(RefPtr& o) 177 { 178 std::swap(m_ptr, o.m_ptr); 179 } 180 181 template<class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) 190 template<class T, typename U> 191 template<typename X, typename Y> 192 inline void RefPtr<T, U>::swap(RefPtr<X, Y>& o) 193 { 194 U::swap(m_ptr, o.m_ptr); 195 } 196 197 template<typename T, typename U, typename X, typename Y, typename = std::enable_if_t<!std::is_same<U, DumbPtrTraits<T>>::value || !std::is_same<Y, DumbPtrTraits<X>>::value>> 198 inline void swap(RefPtr<T, U>& a, RefPtr<X, Y>& b) 182 199 { 183 200 a.swap(b); 184 201 } 185 202 186 template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) 187 { 188 return a.get() == b.get(); 189 } 190 191 template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b) 203 template<typename T, typename U, typename X, typename Y> 204 inline bool operator==(const RefPtr<T, U>& a, const RefPtr<X, Y>& b) 205 { 206 return a.get() == b.get(); 207 } 208 209 template<typename T, typename U, typename X> 210 inline bool operator==(const RefPtr<T, U>& a, X* b) 192 211 { 193 212 return a.get() == b; 194 213 } 195 214 196 template<typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b) 215 template<typename T, typename X, typename Y> 216 inline bool operator==(T* a, const RefPtr<X, Y>& b) 197 217 { 198 218 return a == b.get(); 199 219 } 200 220 201 template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) 221 template<typename T, typename U, typename X, typename Y> 222 inline bool operator!=(const RefPtr<T, U>& a, const RefPtr<X, Y>& b) 202 223 { 203 224 return a.get() != b.get(); 204 225 } 205 226 206 template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b) 227 template<typename T, typename U, typename X> 228 inline bool operator!=(const RefPtr<T, U>& a, X* b) 207 229 { 208 230 return a.get() != b; 209 231 } 210 232 211 template<typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b) 233 template<typename T, typename X, typename Y> 234 inline bool operator!=(T* a, const RefPtr<X, Y>& b) 212 235 { 213 236 return a != b.get(); 214 237 } 215 238 216 template<typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) 217 { 218 return RefPtr<T>(static_cast<T*>(p.get())); 219 } 220 221 template <typename T> struct IsSmartPtr<RefPtr<T>> { 239 template<typename T, typename U = DumbPtrTraits<T>, typename X, typename Y> 240 inline RefPtr<T, U> static_pointer_cast(const RefPtr<X, Y>& p) 241 { 242 return RefPtr<T, U>(static_cast<T*>(p.get())); 243 } 244 245 template <typename T, typename U> 246 struct IsSmartPtr<RefPtr<T, U>> { 222 247 static const bool value = true; 223 248 }; 224 249 225 template<typename T> inline RefPtr<T> adoptRef(T* p) 250 template<typename T, typename U> 251 inline RefPtr<T, U> adoptRef(T* p) 226 252 { 227 253 adopted(p); 228 return RefPtr<T >(p, RefPtr<T>::Adopt);254 return RefPtr<T, U>(p, RefPtr<T, U>::Adopt); 229 255 } 230 256 … … 239 265 } 240 266 241 template<typename ExpectedType, typename ArgType> inline bool is(RefPtr<ArgType>& source) 267 template<typename ExpectedType, typename ArgType, typename PtrTraits> 268 inline bool is(RefPtr<ArgType, PtrTraits>& source) 242 269 { 243 270 return is<ExpectedType>(source.get()); 244 271 } 245 272 246 template<typename ExpectedType, typename ArgType> inline bool is(const RefPtr<ArgType>& source) 273 template<typename ExpectedType, typename ArgType, typename PtrTraits> 274 inline bool is(const RefPtr<ArgType, PtrTraits>& source) 247 275 { 248 276 return is<ExpectedType>(source.get()); 249 277 } 250 278 279 template<uint32_t key, typename T> struct ConstExprPoisonedPtrTraits; 280 281 template<uint32_t key, typename T> 282 using PoisonedRefPtr = RefPtr<T, ConstExprPoisonedPtrTraits<key, T>>; 283 251 284 } // namespace WTF 252 285 286 using WTF::PoisonedRefPtr; 253 287 using WTF::RefPtr; 254 288 using WTF::adoptRef; -
trunk/Tools/ChangeLog
r226009 r226015 1 2017-12-17 Mark Lam <mark.lam@apple.com> 2 3 Enhance Ref and RefPtr to be able to work with smart pointers. 4 https://bugs.webkit.org/show_bug.cgi?id=180762 5 <rdar://problem/36027122> 6 7 Reviewed by JF Bastien and Darin Adler. 8 9 * TestWebKitAPI/CMakeLists.txt: 10 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 11 * TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp: 12 (TestWebKitAPI::TEST): 13 * TestWebKitAPI/Tests/WTF/Poisoned.cpp: 14 (TestWebKitAPI::TEST): 15 * TestWebKitAPI/Tests/WTF/PoisonedRef.cpp: Added. 16 (TestWebKitAPI::TEST): 17 (TestWebKitAPI::passWithRef): 18 (TestWebKitAPI::PoisonedRefCheckingRefLogger::PoisonedRefCheckingRefLogger): 19 (TestWebKitAPI::PoisonedRefCheckingRefLogger::ref): 20 (TestWebKitAPI::PoisonedRefCheckingRefLogger::deref): 21 (TestWebKitAPI::DerivedPoisonedRefCheckingRefLogger::DerivedPoisonedRefCheckingRefLogger): 22 * TestWebKitAPI/Tests/WTF/PoisonedRefPtr.cpp: Added. 23 (TestWebKitAPI::TEST): 24 (TestWebKitAPI::f1): 25 (TestWebKitAPI::ConstRefCounted::create): 26 (TestWebKitAPI::returnConstRefCountedRef): 27 (TestWebKitAPI::returnRefCountedRef): 28 (TestWebKitAPI::PoisonedRefPtrCheckingRefLogger::PoisonedRefPtrCheckingRefLogger): 29 (TestWebKitAPI::loggerName): 30 (TestWebKitAPI::PoisonedRefPtrCheckingRefLogger::ref): 31 (TestWebKitAPI::PoisonedRefPtrCheckingRefLogger::deref): 32 1 33 2017-12-16 Youenn Fablet <youenn@apple.com> 2 34 -
trunk/Tools/TestWebKitAPI/CMakeLists.txt
r225857 r226015 125 125 ${TESTWEBKITAPI_DIR}/Tests/WTF/ParkingLot.cpp 126 126 ${TESTWEBKITAPI_DIR}/Tests/WTF/Poisoned.cpp 127 ${TESTWEBKITAPI_DIR}/Tests/WTF/PoisonedRef.cpp 128 ${TESTWEBKITAPI_DIR}/Tests/WTF/PoisonedRefPtr.cpp 127 129 ${TESTWEBKITAPI_DIR}/Tests/WTF/PriorityQueue.cpp 128 130 ${TESTWEBKITAPI_DIR}/Tests/WTF/RedBlackTree.cpp -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r226008 r226015 758 758 F6F49C6B15545CA70007F39D /* DOMWindowExtensionNoCache_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6F49C6615545C8D0007F39D /* DOMWindowExtensionNoCache_Bundle.cpp */; }; 759 759 F6FDDDD614241C6F004F1729 /* push-state.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F6FDDDD514241C48004F1729 /* push-state.html */; }; 760 FE05FAEC1FDB510A00093230 /* PoisonedRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAEB1FDB510200093230 /* PoisonedRef.cpp */; }; 761 FE05FAED1FDB510E00093230 /* PoisonedRefPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAEA1FDB510100093230 /* PoisonedRefPtr.cpp */; }; 760 762 FE05FAEF1FE0645B00093230 /* Poisoned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAEE1FE0643D00093230 /* Poisoned.cpp */; }; 761 763 FE05FAF11FE08CD400093230 /* ConstExprPoisoned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAF01FE08CCD00093230 /* ConstExprPoisoned.cpp */; }; … … 1862 1864 F6FDDDD214241AD4004F1729 /* PrivateBrowsingPushStateNoHistoryCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateBrowsingPushStateNoHistoryCallback.cpp; sourceTree = "<group>"; }; 1863 1865 F6FDDDD514241C48004F1729 /* push-state.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "push-state.html"; sourceTree = "<group>"; }; 1866 FE05FAEA1FDB510100093230 /* PoisonedRefPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoisonedRefPtr.cpp; sourceTree = "<group>"; }; 1867 FE05FAEB1FDB510200093230 /* PoisonedRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoisonedRef.cpp; sourceTree = "<group>"; }; 1864 1868 FE05FAEE1FE0643D00093230 /* Poisoned.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Poisoned.cpp; sourceTree = "<group>"; }; 1865 1869 FE05FAF01FE08CCD00093230 /* ConstExprPoisoned.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstExprPoisoned.cpp; sourceTree = "<group>"; }; … … 2656 2660 0FE447971B76F1E3009498EB /* ParkingLot.cpp */, 2657 2661 FE05FAEE1FE0643D00093230 /* Poisoned.cpp */, 2662 FE05FAEB1FDB510200093230 /* PoisonedRef.cpp */, 2663 FE05FAEA1FDB510100093230 /* PoisonedRefPtr.cpp */, 2658 2664 53EC253F1E96BC80000831B9 /* PriorityQueue.cpp */, 2659 2665 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */, … … 3187 3193 7C83DEAD1D0A590C00FEBCF3 /* Deque.cpp in Sources */, 3188 3194 1AF7B21F1D6CD14D008C126C /* EnumTraits.cpp in Sources */, 3195 FE05FAED1FDB510E00093230 /* PoisonedRefPtr.cpp in Sources */, 3189 3196 AD7C434D1DD2A54E0026888B /* Expected.cpp in Sources */, 3190 3197 9310CD381EF708FB0050FFE0 /* Function.cpp in Sources */, … … 3204 3211 7C83DEEF1D0A590C00FEBCF3 /* MD5.cpp in Sources */, 3205 3212 7C83DEF11D0A590C00FEBCF3 /* MediaTime.cpp in Sources */, 3213 FE05FAEC1FDB510A00093230 /* PoisonedRef.cpp in Sources */, 3206 3214 7C83DEF61D0A590C00FEBCF3 /* MetaAllocator.cpp in Sources */, 3207 3215 7C83DEFE1D0A590C00FEBCF3 /* NakedPtr.cpp in Sources */, -
trunk/Tools/TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp
r225857 r226015 50 50 ASSERT_EQ(&a, &*ptr); 51 51 ASSERT_EQ(&a.name, &ptr->name); 52 53 #if ENABLE(POISON) 54 uintptr_t ptrBits; 55 std::memcpy(&ptrBits, &ptr, sizeof(ptrBits)); 56 ASSERT_TRUE(ptrBits != bitwise_cast<uintptr_t>(&a)); 57 #if ENABLE(POISON_ASSERTS) 58 ASSERT_TRUE((ConstExprPoisoned<PoisonA, RefLogger*>::isPoisoned(ptrBits))); 59 #endif 60 #endif // ENABLE(POISON) 52 61 } 53 62 -
trunk/Tools/TestWebKitAPI/Tests/WTF/Poisoned.cpp
r225857 r226015 62 62 ASSERT_EQ(&a, &*ptr); 63 63 ASSERT_EQ(&a.name, &ptr->name); 64 65 #if ENABLE(POISON) 66 uintptr_t ptrBits; 67 std::memcpy(&ptrBits, &ptr, sizeof(ptrBits)); 68 ASSERT_TRUE(ptrBits != bitwise_cast<uintptr_t>(&a)); 69 #if ENABLE(POISON_ASSERTS) 70 ASSERT_TRUE((Poisoned<g_testPoisonA, RefLogger*>::isPoisoned(ptrBits))); 71 #endif 72 #endif // ENABLE(POISON) 64 73 } 65 74
Note:
See TracChangeset
for help on using the changeset viewer.