Title: [153637] trunk/Source/WTF
Revision
153637
Author
mr...@apple.com
Date
2013-08-02 00:51:49 -0700 (Fri, 02 Aug 2013)

Log Message

<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.

Modified Paths

Diff

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
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to