Index: public/platform/WebPrivatePtr.h |
diff --git a/public/platform/WebPrivatePtr.h b/public/platform/WebPrivatePtr.h |
index a0b57c9a41b70178e273615194888766576cf7c5..fdb480cfcf2aa15807451ed8c8b1380833ee32b6 100644 |
--- a/public/platform/WebPrivatePtr.h |
+++ b/public/platform/WebPrivatePtr.h |
@@ -34,11 +34,103 @@ |
#include "WebCommon.h" |
#if INSIDE_BLINK |
+#include "heap/Handle.h" |
#include "wtf/PassRefPtr.h" |
#endif |
namespace blink { |
+#if INSIDE_BLINK |
+template<typename T, bool IsGarbageCollected> |
+class PtrStorageImpl; |
+ |
+template<typename T> |
+class PtrStorageImpl<T, false> { |
+public: |
+ typedef PassRefPtr<T> BlinkPtrType; |
+ |
+ void assign(const BlinkPtrType& val) |
+ { |
+ release(); |
+ m_ptr = val.leakRef(); |
+ } |
+ |
+ void assign(const PtrStorageImpl& other) |
+ { |
+ release(); |
+ T* val = other.get(); |
+ if (val) |
+ val->ref(); |
+ m_ptr = val; |
+ } |
+ |
+ T* get() const { return m_ptr; } |
+ |
+ void release() |
+ { |
+ if (m_ptr) |
+ m_ptr->deref(); |
+ m_ptr = 0; |
+ } |
+ |
+private: |
+ T* m_ptr; |
+}; |
+ |
+template<typename T> |
+class PtrStorageImpl<T, true> { |
+ typedef WebCore::Persistent<T> HandleType; |
+public: |
+ typedef RawPtr<T> BlinkPtrType; |
+ |
+ void assign(const BlinkPtrType& val) |
+ { |
+ if (!val) { |
+ release(); |
+ return; |
+ } |
+ |
+ if (!m_handle) |
+ m_handle = new HandleType(); |
+ |
+ (*m_handle) = val; |
+ } |
+ |
+ void assign(const PtrStorageImpl& other) { assign(other.get()); } |
+ |
+ T* get() const { return m_handle ? m_handle->get() : 0; } |
+ |
+ void release() |
+ { |
+ delete m_handle; |
+ m_handle = 0; |
+ } |
+ |
+private: |
+ HandleType* m_handle; |
+}; |
+ |
+template<typename T> |
+class PtrStorage : public PtrStorageImpl<T, WTF::IsSubclassOfTemplate<T, WebCore::GarbageCollected>::value> { |
+public: |
+ static PtrStorage& fromSlot(void** slot) |
+ { |
+ COMPILE_ASSERT(sizeof(PtrStorage) == sizeof(void*), PtrStorage_must_be_pointer_size); |
+ return *reinterpret_cast<PtrStorage*>(slot); |
+ } |
+ |
+ static const PtrStorage& fromSlot(void* const* slot) |
+ { |
+ COMPILE_ASSERT(sizeof(PtrStorage) == sizeof(void*), PtrStorage_must_be_pointer_size); |
+ return *reinterpret_cast<const PtrStorage*>(slot); |
+ } |
+ |
+private: |
+ PtrStorage(); |
+ PtrStorage(const PtrStorage&); |
+}; |
+#endif |
+ |
// This class is an implementation detail of the Blink API. It exists to help |
// simplify the implementation of Blink interfaces that merely wrap a reference |
// counted WebCore class. |
@@ -78,66 +170,57 @@ namespace blink { |
template <typename T> |
class WebPrivatePtr { |
public: |
- WebPrivatePtr() : m_ptr(0) { } |
+ WebPrivatePtr() : m_storage(0) { } |
~WebPrivatePtr() |
{ |
// We don't destruct the object pointed by m_ptr here because we don't |
// want to expose destructors of core classes to embedders. We should |
// call reset() manually in destructors of classes with WebPrivatePtr |
// members. |
- BLINK_ASSERT(!m_ptr); |
+ BLINK_ASSERT(!m_storage); |
} |
- bool isNull() const { return !m_ptr; } |
+ bool isNull() const { return !m_storage; } |
#if INSIDE_BLINK |
- WebPrivatePtr(const PassRefPtr<T>& prp) |
- : m_ptr(prp.leakRef()) |
+ template<typename U> |
+ WebPrivatePtr(const U& ptr) // Can't use PtrStorage<T>::BlinkPtrType because it will cause early instantiation. |
+ : m_storage(0) |
{ |
+ storage().assign(ptr); |
} |
- void reset() |
- { |
- assign(0); |
- } |
+ void reset() { storage().release(); } |
WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other) |
{ |
- T* p = other.m_ptr; |
- if (p) |
- p->ref(); |
- assign(p); |
+ storage().assign(other.storage()); |
return *this; |
} |
- WebPrivatePtr<T>& operator=(const PassRefPtr<T>& prp) |
+ template<typename U> |
+ WebPrivatePtr<T>& operator=(const U& ptr) // Can't use PtrStorage<T>::BlinkPtrType because it will cause early instantiation. |
{ |
- assign(prp.leakRef()); |
+ storage().assign(ptr); |
return *this; |
} |
- T* get() const |
- { |
- return m_ptr; |
- } |
+ T* get() const { return storage().get(); } |
T* operator->() const |
{ |
- ASSERT(m_ptr); |
- return m_ptr; |
+ ASSERT(m_storage); |
+ return get(); |
} |
#endif |
private: |
#if INSIDE_BLINK |
- void assign(T* p) |
- { |
- // p is already ref'd for us by the caller |
- if (m_ptr) |
- m_ptr->deref(); |
- m_ptr = p; |
- } |
-#else |
+ PtrStorage<T>& storage() { return PtrStorage<T>::fromSlot(&m_storage); } |
+ const PtrStorage<T>& storage() const { return PtrStorage<T>::fromSlot(&m_storage); } |
+#endif |
+ |
+#if !INSIDE_BLINK |
// Disable the assignment operator; we define it above for when |
// INSIDE_BLINK is set, but we need to make sure that it is not |
// used outside there; the compiler-provided version won't handle reference |
@@ -148,7 +231,7 @@ private: |
// should implement their copy constructor using assign(). |
WebPrivatePtr(const WebPrivatePtr<T>&); |
- T* m_ptr; |
+ void* m_storage; |
}; |
} // namespace blink |