X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/1df5f87f1309a8daa30dabdee855f48ae40d14ab..6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174:/heap/PassWeak.h diff --git a/heap/PassWeak.h b/heap/PassWeak.h new file mode 100644 index 0000000..8c6364e --- /dev/null +++ b/heap/PassWeak.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PassWeak_h +#define PassWeak_h + +#include "JSCell.h" +#include "WeakSetInlines.h" +#include +#include +#include + +namespace JSC { + +template class Weak; +template class PassWeak; +template PassWeak adoptWeak(WeakImpl*); + +template class WeakImplAccessor { +public: + typedef T* GetType; + + T* operator->() const; + T& operator*() const; + GetType get() const; + +#if !ASSERT_DISABLED + bool was(GetType) const; +#endif +}; + +template class PassWeak : public WeakImplAccessor, T> { +public: + friend class WeakImplAccessor, T>; + typedef typename WeakImplAccessor, T>::GetType GetType; + + PassWeak(); + PassWeak(std::nullptr_t); + PassWeak(GetType, WeakHandleOwner* = 0, void* context = 0); + + // It somewhat breaks the type system to allow transfer of ownership out of + // a const PassWeak. However, it makes it much easier to work with PassWeak + // temporaries, and we don't have a need to use real const PassWeaks anyway. + PassWeak(const PassWeak&); + template PassWeak(const PassWeak&); + + ~PassWeak(); + + bool operator!() const; + + // This conversion operator allows implicit conversion to bool but not to other integer types. + typedef JSValue (PassWeak::*UnspecifiedBoolType); + operator UnspecifiedBoolType*() const; + + WeakImpl* leakImpl() const WARN_UNUSED_RETURN; + +private: + friend PassWeak adoptWeak(WeakImpl*); + explicit PassWeak(WeakImpl*); + + WeakImpl* m_impl; +}; + +template inline T* WeakImplAccessor::operator->() const +{ + ASSERT(static_cast(this)->m_impl && static_cast(this)->m_impl->state() == WeakImpl::Live); + return jsCast(static_cast(this)->m_impl->jsValue().asCell()); +} + +template inline T& WeakImplAccessor::operator*() const +{ + ASSERT(static_cast(this)->m_impl && static_cast(this)->m_impl->state() == WeakImpl::Live); + return *jsCast(static_cast(this)->m_impl->jsValue().asCell()); +} + +template inline typename WeakImplAccessor::GetType WeakImplAccessor::get() const +{ + if (!static_cast(this)->m_impl || static_cast(this)->m_impl->state() != WeakImpl::Live) + return GetType(); + return jsCast(static_cast(this)->m_impl->jsValue().asCell()); +} + +#if !ASSERT_DISABLED +template inline bool WeakImplAccessor::was(typename WeakImplAccessor::GetType other) const +{ + return jsCast(static_cast(this)->m_impl->jsValue().asCell()) == other; +} +#endif + +template inline PassWeak::PassWeak() + : m_impl(0) +{ +} + +template inline PassWeak::PassWeak(std::nullptr_t) + : m_impl(0) +{ +} + +template inline PassWeak::PassWeak(typename PassWeak::GetType getType, WeakHandleOwner* weakOwner, void* context) + : m_impl(getType ? WeakSet::allocate(getType, weakOwner, context) : 0) +{ +} + +template inline PassWeak::PassWeak(const PassWeak& o) + : m_impl(o.leakImpl()) +{ +} + +template template inline PassWeak::PassWeak(const PassWeak& o) + : m_impl(o.leakImpl()) +{ +} + +template inline PassWeak::~PassWeak() +{ + if (!m_impl) + return; + WeakSet::deallocate(m_impl); +} + +template inline bool PassWeak::operator!() const +{ + return !m_impl || m_impl->state() != WeakImpl::Live || !m_impl->jsValue(); +} + +template inline PassWeak::operator UnspecifiedBoolType*() const +{ + return reinterpret_cast(!!*this); +} + +template inline PassWeak::PassWeak(WeakImpl* impl) +: m_impl(impl) +{ +} + +template inline WeakImpl* PassWeak::leakImpl() const +{ + WeakImpl* tmp = 0; + std::swap(tmp, const_cast(m_impl)); + return tmp; +} + +template PassWeak inline adoptWeak(WeakImpl* impl) +{ + return PassWeak(impl); +} + +template inline bool operator==(const PassWeak& a, const PassWeak& b) +{ + return a.get() == b.get(); +} + +template inline bool operator==(const PassWeak& a, const Weak& b) +{ + return a.get() == b.get(); +} + +template inline bool operator==(const Weak& a, const PassWeak& b) +{ + return a.get() == b.get(); +} + +template inline bool operator==(const PassWeak& a, U* b) +{ + return a.get() == b; +} + +template inline bool operator==(T* a, const PassWeak& b) +{ + return a == b.get(); +} + +template inline bool operator!=(const PassWeak& a, const PassWeak& b) +{ + return a.get() != b.get(); +} + +template inline bool operator!=(const PassWeak& a, const Weak& b) +{ + return a.get() != b.get(); +} + +template inline bool operator!=(const Weak& a, const PassWeak& b) +{ + return a.get() != b.get(); +} + +template inline bool operator!=(const PassWeak& a, U* b) +{ + return a.get() != b; +} + +template inline bool operator!=(T* a, const PassWeak& b) +{ + return a != b.get(); +} + +} // namespace JSC + +#endif // PassWeak_h