Title: [154538] trunk/Source/WTF
- Revision
- 154538
- Author
- [email protected]
- Date
- 2013-08-23 21:07:20 -0700 (Fri, 23 Aug 2013)
Log Message
<https://webkit.org/b/120141> Make RetainPtr work with ARC.
Have RetainPtr store the object its managing as a CFTypeRef and manage its lifetime with
CFRetain / CFRelease. This is necessary to have explicit control over the lifetime of
Objective-C objects when automatic reference counting is in use. Two helper methods are
introduced to convert between the pointer type that the RetainPtr manages and the CFTypeRef
that the pointer is stored as. For CF types and Objective-C types with ARC disabled,
these methods are simply casts. For Objective-C types under ARC they need to use the
special bridging casts to keep the compiler happy.
Reviewed by Anders Carlsson.
* wtf/RetainPtr.h:
(WTF::RetainPtr::RetainPtr): Use the helper methods to convert to and from the storage
types when necessary.
(WTF::RetainPtr::~RetainPtr): Ditto.
(WTF::RetainPtr::get): Ditto.
(WTF::RetainPtr::operator->): Ditto.
(WTF::RetainPtr::operator PtrType): Ditto.
(WTF::::RetainPtr): Ditto.
(WTF::::clear): Ditto.
(WTF::::leakRef): Ditto.
(WTF::=): Ditto.
(WTF::RetainPtr::fromStorageTypeHelper): Use crazy template magic to determine whether to use
a bridging cast or not depending on the desired return type.
(WTF::RetainPtr::fromStorageType):
(WTF::RetainPtr::toStorageType): Overloading is sufficient here.
Modified Paths
Diff
Modified: trunk/Source/WTF/ChangeLog (154537 => 154538)
--- trunk/Source/WTF/ChangeLog 2013-08-24 04:07:07 UTC (rev 154537)
+++ trunk/Source/WTF/ChangeLog 2013-08-24 04:07:20 UTC (rev 154538)
@@ -1,5 +1,36 @@
2013-08-21 Mark Rowe <[email protected]>
+ <https://webkit.org/b/120141> Make RetainPtr work with ARC.
+
+ Have RetainPtr store the object its managing as a CFTypeRef and manage its lifetime with
+ CFRetain / CFRelease. This is necessary to have explicit control over the lifetime of
+ Objective-C objects when automatic reference counting is in use. Two helper methods are
+ introduced to convert between the pointer type that the RetainPtr manages and the CFTypeRef
+ that the pointer is stored as. For CF types and Objective-C types with ARC disabled,
+ these methods are simply casts. For Objective-C types under ARC they need to use the
+ special bridging casts to keep the compiler happy.
+
+ Reviewed by Anders Carlsson.
+
+ * wtf/RetainPtr.h:
+ (WTF::RetainPtr::RetainPtr): Use the helper methods to convert to and from the storage
+ types when necessary.
+ (WTF::RetainPtr::~RetainPtr): Ditto.
+ (WTF::RetainPtr::get): Ditto.
+ (WTF::RetainPtr::operator->): Ditto.
+ (WTF::RetainPtr::operator PtrType): Ditto.
+ (WTF::::RetainPtr): Ditto.
+ (WTF::::clear): Ditto.
+ (WTF::::leakRef): Ditto.
+ (WTF::=): Ditto.
+
+ (WTF::RetainPtr::fromStorageTypeHelper): Use crazy template magic to determine whether to use
+ a bridging cast or not depending on the desired return type.
+ (WTF::RetainPtr::fromStorageType):
+ (WTF::RetainPtr::toStorageType): Overloading is sufficient here.
+
+2013-08-21 Mark Rowe <[email protected]>
+
Revert r153637.
It didn't work with ARC like it said it would. We'll need to take a slightly different approach.
Modified: trunk/Source/WTF/wtf/RetainPtr.h (154537 => 154538)
--- trunk/Source/WTF/wtf/RetainPtr.h 2013-08-24 04:07:07 UTC (rev 154537)
+++ trunk/Source/WTF/wtf/RetainPtr.h 2013-08-24 04:07:20 UTC (rev 154538)
@@ -52,7 +52,7 @@
enum AdoptCFTag { AdoptCF };
enum AdoptNSTag { AdoptNS };
-#ifdef __OBJC__
+#if defined(__OBJC__) && !__has_feature(objc_arc)
#ifdef OBJC_NO_GC
inline void adoptNSReference(id)
{
@@ -72,51 +72,56 @@
public:
typedef typename RemovePointer<T>::Type ValueType;
typedef ValueType* PtrType;
+ typedef CFTypeRef StorageType;
RetainPtr() : m_ptr(0) {}
- RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); }
+ RetainPtr(PtrType ptr) : m_ptr(toStorageType(ptr)) { if (m_ptr) CFRetain(m_ptr); }
RetainPtr(AdoptCFTag, PtrType ptr)
- : m_ptr(ptr)
+ : m_ptr(toStorageType(ptr))
{
#ifdef __OBJC__
static_assert((!std::is_convertible<T, id>::value), "Don't use adoptCF with Objective-C pointer types, use adoptNS.");
#endif
}
+#if __has_feature(objc_arc)
+ RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(toStorageType(ptr)) { if (m_ptr) CFRetain(m_ptr); }
+#else
RetainPtr(AdoptNSTag, PtrType ptr)
- : m_ptr(ptr)
+ : m_ptr(toStorageType(ptr))
{
adoptNSReference(ptr);
}
+#endif
- RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (PtrType ptr = m_ptr) CFRetain(ptr); }
+ RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (StorageType ptr = m_ptr) CFRetain(ptr); }
#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
- RetainPtr(RetainPtr&& o) : m_ptr(o.leakRef()) { }
+ RetainPtr(RetainPtr&& o) : m_ptr(toStorageType(o.leakRef())) { }
#endif
// Hash table deleted values, which are only constructed and never copied or destroyed.
RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
- ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); }
+ ~RetainPtr() { if (StorageType ptr = m_ptr) CFRelease(ptr); }
template<typename U> RetainPtr(const RetainPtr<U>&);
void clear();
PtrType leakRef() WARN_UNUSED_RETURN;
- PtrType get() const { return m_ptr; }
- PtrType operator->() const { return m_ptr; }
+ PtrType get() const { return fromStorageType(m_ptr); }
+ PtrType operator->() const { return fromStorageType(m_ptr); }
#if COMPILER_SUPPORTS(CXX_EXPLICIT_CONVERSIONS)
- explicit operator PtrType() const { return m_ptr; }
+ explicit operator PtrType() const { return fromStorageType(m_ptr); }
#endif
bool operator!() const { return !m_ptr; }
// This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef PtrType RetainPtr::*UnspecifiedBoolType;
+ typedef StorageType RetainPtr::*UnspecifiedBoolType;
operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; }
RetainPtr& operator=(const RetainPtr&);
@@ -138,19 +143,42 @@
private:
static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1); }
- PtrType m_ptr;
+#if defined (__OBJC__) && __has_feature(objc_arc)
+ template<typename U>
+ typename std::enable_if<std::is_convertible<U, id>::value, PtrType>::type
+ fromStorageTypeHelper(StorageType ptr) const
+ {
+ return (__bridge PtrType)ptr;
+ }
+
+ template<typename U>
+ typename std::enable_if<!std::is_convertible<U, id>::value, PtrType>::type
+ fromStorageTypeHelper(StorageType ptr) const
+ {
+ return (PtrType)ptr;
+ }
+
+ PtrType fromStorageType(StorageType ptr) const { return fromStorageTypeHelper<PtrType>(ptr); }
+ StorageType toStorageType(id ptr) const { return (__bridge StorageType)ptr; }
+ StorageType toStorageType(CFTypeRef ptr) const { return (StorageType)ptr; }
+#else
+ PtrType fromStorageType(StorageType ptr) const { return (PtrType)ptr; }
+ StorageType toStorageType(PtrType ptr) const { return (StorageType)ptr; }
+#endif
+
+ StorageType m_ptr;
};
template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o)
- : m_ptr(o.get())
+ : m_ptr(toStorageType(o.get()))
{
- if (PtrType ptr = m_ptr)
+ if (StorageType ptr = m_ptr)
CFRetain(ptr);
}
template<typename T> inline void RetainPtr<T>::clear()
{
- if (PtrType ptr = m_ptr) {
+ if (StorageType ptr = m_ptr) {
m_ptr = 0;
CFRelease(ptr);
}
@@ -158,7 +186,7 @@
template<typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef()
{
- PtrType ptr = m_ptr;
+ PtrType ptr = fromStorageType(m_ptr);
m_ptr = 0;
return ptr;
}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes