Modified: trunk/Source/WTF/ChangeLog (153636 => 153637)
--- trunk/Source/WTF/ChangeLog 2013-08-02 06:09:05 UTC (rev 153636)
+++ trunk/Source/WTF/ChangeLog 2013-08-02 07:51:49 UTC (rev 153637)
@@ -1,3 +1,38 @@
+2013-07-26 Mark Rowe <mr...@apple.com>
+
+ <http://webkit.org/b/119169> RetainPtr should support ARC for Objective-C objects.
+
+ While RetainPtr is not necessary under ARC, having it available makes it easier to transition
+ existing code from manual retain / release to ARC.
+
+ Under ARC, the object member of RetainPtr is treated as a strong reference by the compiler.
+ This means that merely assigning to the member variable is sufficient to retain the object,
+ and clearing the member variable is sufficient to release it. We still need to explicitly
+ CFRetain / CFRelease CoreFoundation types so the explicit calls to these functions are
+ moved in to helper functions and overloading is used to have the Objective-C object versions
+ of them be no-ops under ARC.
+
+ Reviewed by Anders Carlsson.
+
+ * wtf/RetainPtr.h:
+ (WTF::retain): Continue to always CFRetain / CFRelease CoreFoundation objects. Only CFRetain / CFRelease
+ Objective-C objects when using manual retain / release.
+ (WTF::release): Ditto.
+ (WTF::adoptNSReference): Adopting references will be handled automatically by the compiler
+ when possible under ARC by eliminating redundant retain / release pairs.
+ (WTF::RetainPtr::ImplicitConversionToBoolIsNotAllowed): A new method that exists only to be used by the
+ conversion to the unspecified bool type.
+ (WTF::RetainPtr::operator UnspecifiedBoolType): Switch to using a pointer to a member function as the
+ unspecified bool type to avoid warnings from the compiler when casting Objective-C object types under ARC.
+
+ (WTF::RetainPtr::RetainPtr): Switch to our retain / release helper functions.
+ (WTF::RetainPtr::~RetainPtr): Ditto.
+ (WTF::::RetainPtr): Ditto.
+ (WTF::::clear): Ditto.
+ (WTF::=): Ditto.
+ (WTF::adoptCF): Annotate the argument with CF_RELEASES_ARGUMENT on both the declaration and the definition.
+ (WTF::adoptNS): Ditto for NS_RELEASES_ARGUMENT.
+
2013-08-01 Mark Rowe <mr...@apple.com>
<rdar://problem/14235491> FastMalloc zone enumerator responding to MALLOC_PTR_REGION_RANGE_TYPE with individual allocations
Modified: trunk/Source/WTF/wtf/RetainPtr.h (153636 => 153637)
--- trunk/Source/WTF/wtf/RetainPtr.h 2013-08-02 06:09:05 UTC (rev 153636)
+++ trunk/Source/WTF/wtf/RetainPtr.h 2013-08-02 07:51:49 UTC (rev 153637)
@@ -21,6 +21,8 @@
#ifndef RetainPtr_h
#define RetainPtr_h
+#if USE(CF) || defined(__OBJC__)
+
#include <wtf/HashTraits.h>
#include <wtf/NullPtr.h>
#include <wtf/TypeTraits.h>
@@ -49,8 +51,28 @@
enum AdoptCFTag { AdoptCF };
enum AdoptNSTag { AdoptNS };
-
+
+#if USE(CF)
+ inline void retain(CFTypeRef ptr) { CFRetain(ptr); }
+ inline void release(CFTypeRef ptr) { CFRelease(ptr); }
+#endif
+
#ifdef __OBJC__
+#if __has_feature(objc_arc)
+ inline void adoptNSReference(id) { }
+ inline void retain(id ptr) { }
+ inline void release(id ptr) { }
+#else
+ inline void retain(id ptr)
+ {
+ CFRetain(ptr);
+ }
+
+ inline void release(id ptr)
+ {
+ CFRelease(ptr);
+ }
+
#ifdef OBJC_NO_GC
inline void adoptNSReference(id)
{
@@ -64,15 +86,17 @@
}
}
#endif
-#endif
+#endif // __has_feature(objc_arc)
+#endif // __OBJC__
+
template<typename T> class RetainPtr {
public:
typedef typename RemovePointer<T>::Type ValueType;
typedef ValueType* PtrType;
RetainPtr() : m_ptr(0) {}
- RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); }
+ RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) retain(ptr); }
RetainPtr(AdoptCFTag, PtrType ptr)
: m_ptr(ptr)
@@ -88,7 +112,7 @@
adoptNSReference(ptr);
}
- 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 (PtrType ptr = m_ptr) retain(ptr); }
#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
RetainPtr(RetainPtr&& o) : m_ptr(o.leakRef()) { }
@@ -98,7 +122,7 @@
RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
- ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); }
+ ~RetainPtr() { if (PtrType ptr = m_ptr) release(ptr); }
template<typename U> RetainPtr(const RetainPtr<U>&);
@@ -114,8 +138,9 @@
bool operator!() const { return !m_ptr; }
// This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef PtrType RetainPtr::*UnspecifiedBoolType;
- operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; }
+ typedef void (RetainPtr::*UnspecifiedBoolType)() const;
+ void ImplicitConversionToBoolIsNotAllowed() const { }
+ operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::ImplicitConversionToBoolIsNotAllowed : 0; }
RetainPtr& operator=(const RetainPtr&);
template<typename U> RetainPtr& operator=(const RetainPtr<U>&);
@@ -143,14 +168,14 @@
: m_ptr(o.get())
{
if (PtrType ptr = m_ptr)
- CFRetain(ptr);
+ retain(ptr);
}
template<typename T> inline void RetainPtr<T>::clear()
{
if (PtrType ptr = m_ptr) {
m_ptr = 0;
- CFRelease(ptr);
+ release(ptr);
}
}
@@ -165,11 +190,11 @@
{
PtrType optr = o.get();
if (optr)
- CFRetain(optr);
+ retain(optr);
PtrType ptr = m_ptr;
m_ptr = optr;
if (ptr)
- CFRelease(ptr);
+ release(ptr);
return *this;
}
@@ -177,33 +202,33 @@
{
PtrType optr = o.get();
if (optr)
- CFRetain(optr);
+ retain(optr);
PtrType ptr = m_ptr;
m_ptr = optr;
if (ptr)
- CFRelease(ptr);
+ release(ptr);
return *this;
}
template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr)
{
if (optr)
- CFRetain(optr);
+ retain(optr);
PtrType ptr = m_ptr;
m_ptr = optr;
if (ptr)
- CFRelease(ptr);
+ release(ptr);
return *this;
}
template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr)
{
if (optr)
- CFRetain(optr);
+ retain(optr);
PtrType ptr = m_ptr;
m_ptr = optr;
if (ptr)
- CFRelease(ptr);
+ release(ptr);
return *this;
}
@@ -213,7 +238,7 @@
PtrType ptr = m_ptr;
m_ptr = o.leakRef();
if (ptr)
- CFRelease(ptr);
+ release(ptr);
return *this;
}
@@ -223,7 +248,7 @@
PtrType ptr = m_ptr;
m_ptr = o.leakRef();
if (ptr)
- CFRelease(ptr);
+ release(ptr);
return *this;
}
#endif
@@ -269,13 +294,13 @@
}
template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
- template<typename T> inline RetainPtr<T> adoptCF(T o)
+ template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT o)
{
return RetainPtr<T>(AdoptCF, o);
}
template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
- template<typename T> inline RetainPtr<T> adoptNS(T o)
+ template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT o)
{
return RetainPtr<T>(AdoptNS, o);
}
@@ -331,4 +356,6 @@
using WTF::RetainPtr;
using WTF::retainPtr;
+#endif // USE(CF) || defined(__OBJC__)
+
#endif // WTF_RetainPtr_h