]> git.saurik.com Git - apple/javascriptcore.git/blob - heap/PassWeak.h
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / heap / PassWeak.h
1 /*
2 * Copyright (C) 2012 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #ifndef PassWeak_h
27 #define PassWeak_h
28
29 #include "JSCell.h"
30 #include "WeakSetInlines.h"
31 #include <wtf/Assertions.h>
32 #include <wtf/NullPtr.h>
33 #include <wtf/TypeTraits.h>
34
35 namespace JSC {
36
37 template<typename T> class Weak;
38 template<typename T> class PassWeak;
39 template<typename T> PassWeak<T> adoptWeak(WeakImpl*);
40
41 template<typename Base, typename T> class WeakImplAccessor {
42 public:
43 typedef T* GetType;
44
45 T* operator->() const;
46 T& operator*() const;
47 GetType get() const;
48
49 #if !ASSERT_DISABLED
50 bool was(GetType) const;
51 #endif
52 };
53
54 template<typename T> class PassWeak : public WeakImplAccessor<PassWeak<T>, T> {
55 public:
56 friend class WeakImplAccessor<PassWeak<T>, T>;
57 typedef typename WeakImplAccessor<PassWeak<T>, T>::GetType GetType;
58
59 PassWeak();
60 PassWeak(std::nullptr_t);
61 PassWeak(GetType, WeakHandleOwner* = 0, void* context = 0);
62
63 // It somewhat breaks the type system to allow transfer of ownership out of
64 // a const PassWeak. However, it makes it much easier to work with PassWeak
65 // temporaries, and we don't have a need to use real const PassWeaks anyway.
66 PassWeak(const PassWeak&);
67 template<typename U> PassWeak(const PassWeak<U>&);
68
69 ~PassWeak();
70
71 bool operator!() const;
72
73 // This conversion operator allows implicit conversion to bool but not to other integer types.
74 typedef JSValue (PassWeak::*UnspecifiedBoolType);
75 operator UnspecifiedBoolType*() const;
76
77 WeakImpl* leakImpl() const WARN_UNUSED_RETURN;
78
79 private:
80 friend PassWeak adoptWeak<T>(WeakImpl*);
81 explicit PassWeak(WeakImpl*);
82
83 WeakImpl* m_impl;
84 };
85
86 template<typename Base, typename T> inline T* WeakImplAccessor<Base, T>::operator->() const
87 {
88 ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live);
89 return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell());
90 }
91
92 template<typename Base, typename T> inline T& WeakImplAccessor<Base, T>::operator*() const
93 {
94 ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live);
95 return *jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell());
96 }
97
98 template<typename Base, typename T> inline typename WeakImplAccessor<Base, T>::GetType WeakImplAccessor<Base, T>::get() const
99 {
100 if (!static_cast<const Base*>(this)->m_impl || static_cast<const Base*>(this)->m_impl->state() != WeakImpl::Live)
101 return GetType();
102 return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell());
103 }
104
105 #if !ASSERT_DISABLED
106 template<typename Base, typename T> inline bool WeakImplAccessor<Base, T>::was(typename WeakImplAccessor<Base, T>::GetType other) const
107 {
108 return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell()) == other;
109 }
110 #endif
111
112 template<typename T> inline PassWeak<T>::PassWeak()
113 : m_impl(0)
114 {
115 }
116
117 template<typename T> inline PassWeak<T>::PassWeak(std::nullptr_t)
118 : m_impl(0)
119 {
120 }
121
122 template<typename T> inline PassWeak<T>::PassWeak(typename PassWeak<T>::GetType getType, WeakHandleOwner* weakOwner, void* context)
123 : m_impl(getType ? WeakSet::allocate(getType, weakOwner, context) : 0)
124 {
125 }
126
127 template<typename T> inline PassWeak<T>::PassWeak(const PassWeak& o)
128 : m_impl(o.leakImpl())
129 {
130 }
131
132 template<typename T> template<typename U> inline PassWeak<T>::PassWeak(const PassWeak<U>& o)
133 : m_impl(o.leakImpl())
134 {
135 }
136
137 template<typename T> inline PassWeak<T>::~PassWeak()
138 {
139 if (!m_impl)
140 return;
141 WeakSet::deallocate(m_impl);
142 }
143
144 template<typename T> inline bool PassWeak<T>::operator!() const
145 {
146 return !m_impl || m_impl->state() != WeakImpl::Live || !m_impl->jsValue();
147 }
148
149 template<typename T> inline PassWeak<T>::operator UnspecifiedBoolType*() const
150 {
151 return reinterpret_cast<UnspecifiedBoolType*>(!!*this);
152 }
153
154 template<typename T> inline PassWeak<T>::PassWeak(WeakImpl* impl)
155 : m_impl(impl)
156 {
157 }
158
159 template<typename T> inline WeakImpl* PassWeak<T>::leakImpl() const
160 {
161 WeakImpl* tmp = 0;
162 std::swap(tmp, const_cast<WeakImpl*&>(m_impl));
163 return tmp;
164 }
165
166 template<typename T> PassWeak<T> inline adoptWeak(WeakImpl* impl)
167 {
168 return PassWeak<T>(impl);
169 }
170
171 template<typename T, typename U> inline bool operator==(const PassWeak<T>& a, const PassWeak<U>& b)
172 {
173 return a.get() == b.get();
174 }
175
176 template<typename T, typename U> inline bool operator==(const PassWeak<T>& a, const Weak<U>& b)
177 {
178 return a.get() == b.get();
179 }
180
181 template<typename T, typename U> inline bool operator==(const Weak<T>& a, const PassWeak<U>& b)
182 {
183 return a.get() == b.get();
184 }
185
186 template<typename T, typename U> inline bool operator==(const PassWeak<T>& a, U* b)
187 {
188 return a.get() == b;
189 }
190
191 template<typename T, typename U> inline bool operator==(T* a, const PassWeak<U>& b)
192 {
193 return a == b.get();
194 }
195
196 template<typename T, typename U> inline bool operator!=(const PassWeak<T>& a, const PassWeak<U>& b)
197 {
198 return a.get() != b.get();
199 }
200
201 template<typename T, typename U> inline bool operator!=(const PassWeak<T>& a, const Weak<U>& b)
202 {
203 return a.get() != b.get();
204 }
205
206 template<typename T, typename U> inline bool operator!=(const Weak<T>& a, const PassWeak<U>& b)
207 {
208 return a.get() != b.get();
209 }
210
211 template<typename T, typename U> inline bool operator!=(const PassWeak<T>& a, U* b)
212 {
213 return a.get() != b;
214 }
215
216 template<typename T, typename U> inline bool operator!=(T* a, const PassWeak<U>& b)
217 {
218 return a != b.get();
219 }
220
221 } // namespace JSC
222
223 #endif // PassWeak_h