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