| Index: public/platform/WebPrivatePtr.h | 
| diff --git a/public/platform/WebPrivatePtr.h b/public/platform/WebPrivatePtr.h | 
| index a0b57c9a41b70178e273615194888766576cf7c5..b914710fc0781697fd6d3047b94b77ca3531dbaa 100644 | 
| --- a/public/platform/WebPrivatePtr.h | 
| +++ b/public/platform/WebPrivatePtr.h | 
| @@ -34,11 +34,128 @@ | 
| #include "WebCommon.h" | 
|  | 
| #if INSIDE_BLINK | 
| +#include "heap/Handle.h" | 
| #include "wtf/PassRefPtr.h" | 
| +#include "wtf/TypeTraits.h" | 
| #endif | 
|  | 
| namespace blink { | 
|  | 
| +#if INSIDE_BLINK | 
| +enum LifetimeManagementType { | 
| +    RefCountedLifetime, | 
| +    GarbageCollectedLifetime, | 
| +    RefCountedGarbageCollectedLifetime | 
| +}; | 
| + | 
| +template<typename T> | 
| +class LifetimeOf { | 
| +    static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, WebCore::GarbageCollected>::value; | 
| +    static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T, WebCore::RefCountedGarbageCollected>::value; | 
| +public: | 
| +    static const LifetimeManagementType value = | 
| +        !isGarbageCollected          ? RefCountedLifetime : | 
| +        isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : GarbageCollectedLifetime; | 
| +}; | 
| + | 
| +template<typename T, LifetimeManagementType lifetime> | 
| +class PtrStorageImpl; | 
| + | 
| +template<typename T> | 
| +class PtrStorageImpl<T, RefCountedLifetime> { | 
| +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, GarbageCollectedLifetime> { | 
| +public: | 
| +    void assign(const RawPtr<T>& val) | 
| +    { | 
| +        if (!val) { | 
| +            release(); | 
| +            return; | 
| +        } | 
| + | 
| +        if (!m_handle) | 
| +            m_handle = new WebCore::Persistent<T>(); | 
| + | 
| +        (*m_handle) = val; | 
| +    } | 
| + | 
| +    void assign(T* ptr) { assign(RawPtr<T>(ptr)); } | 
| + | 
| +    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: | 
| +    WebCore::Persistent<T>* m_handle; | 
| +}; | 
| + | 
| +template<typename T> | 
| +class PtrStorageImpl<T, RefCountedGarbageCollectedLifetime> : public PtrStorageImpl<T, GarbageCollectedLifetime> { | 
| +public: | 
| +    void assign(const PassRefPtr<T>& val) { assign(RawPtr<T>(val.get())); } | 
| + | 
| +    void assign(const PtrStorageImpl& other) { assign(RawPtr<T>(other.get())); } | 
| +}; | 
| + | 
| +template<typename T> | 
| +class PtrStorage : public PtrStorageImpl<T, LifetimeOf<T>::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: | 
| +    // Prevent construction via normal means. | 
| +    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 +195,63 @@ 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) | 
| +        : 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) | 
| +    WebPrivatePtr<T>& operator=(std::nullptr_t) | 
| { | 
| -        assign(prp.leakRef()); | 
| +        reset(); | 
| return *this; | 
| } | 
|  | 
| -    T* get() const | 
| +    template<typename U> | 
| +    WebPrivatePtr<T>& operator=(const U& ptr) | 
| { | 
| -        return m_ptr; | 
| +        storage().assign(ptr); | 
| +        return *this; | 
| } | 
|  | 
| +    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 +262,7 @@ private: | 
| // should implement their copy constructor using assign(). | 
| WebPrivatePtr(const WebPrivatePtr<T>&); | 
|  | 
| -    T* m_ptr; | 
| +    void* m_storage; | 
| }; | 
|  | 
| } // namespace blink | 
|  |