• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef WriteBarrier_h
27 #define WriteBarrier_h
28 
29 #include "JSValue.h"
30 
31 namespace JSC {
32 class JSCell;
33 class JSGlobalData;
34 
writeBarrier(JSGlobalData &,const JSCell *,JSValue)35 inline void writeBarrier(JSGlobalData&, const JSCell*, JSValue)
36 {
37 }
38 
writeBarrier(JSGlobalData &,const JSCell *,JSCell *)39 inline void writeBarrier(JSGlobalData&, const JSCell*, JSCell*)
40 {
41 }
42 
43 typedef enum { } Unknown;
44 typedef JSValue* HandleSlot;
45 
46 template <typename T> struct JSValueChecker {
47     static const bool IsJSValue = false;
48 };
49 
50 template <> struct JSValueChecker<JSValue> {
51     static const bool IsJSValue = true;
52 };
53 
54 // We have a separate base class with no constructors for use in Unions.
55 template <typename T> class WriteBarrierBase {
56 public:
57     COMPILE_ASSERT(!JSValueChecker<T>::IsJSValue, WriteBarrier_JSValue_is_invalid__use_unknown);
58     void set(JSGlobalData& globalData, const JSCell* owner, T* value)
59     {
60         this->m_cell = reinterpret_cast<JSCell*>(value);
61         writeBarrier(globalData, owner, this->m_cell);
62 #if ENABLE(JSC_ZOMBIES)
63         ASSERT(!isZombie(owner));
64         ASSERT(!isZombie(m_cell));
65 #endif
66     }
67 
68     T* get() const
69     {
70         return reinterpret_cast<T*>(m_cell);
71     }
72 
73     T* operator*() const
74     {
75         ASSERT(m_cell);
76 #if ENABLE(JSC_ZOMBIES)
77         ASSERT(!isZombie(m_cell));
78 #endif
79         return static_cast<T*>(m_cell);
80     }
81 
82     T* operator->() const
83     {
84         ASSERT(m_cell);
85         return static_cast<T*>(m_cell);
86     }
87 
88     void clear() { m_cell = 0; }
89 
90     JSCell** slot() { return &m_cell; }
91 
92     typedef T* (WriteBarrierBase::*UnspecifiedBoolType);
93     operator UnspecifiedBoolType*() const { return m_cell ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
94 
95     bool operator!() const { return !m_cell; }
96 
97     void setWithoutWriteBarrier(T* value)
98     {
99         this->m_cell = reinterpret_cast<JSCell*>(value);
100 #if ENABLE(JSC_ZOMBIES)
101         ASSERT(!m_cell || !isZombie(m_cell));
102 #endif
103     }
104 
105 private:
106     JSCell* m_cell;
107 };
108 
109 template <> class WriteBarrierBase<Unknown> {
110 public:
111     void set(JSGlobalData& globalData, const JSCell* owner, JSValue value)
112     {
113 #if ENABLE(JSC_ZOMBIES)
114         ASSERT(!isZombie(owner));
115         ASSERT(!value.isZombie());
116 #endif
117         m_value = JSValue::encode(value);
118         writeBarrier(globalData, owner, value);
119     }
120     void setWithoutWriteBarrier(JSValue value)
121     {
122 #if ENABLE(JSC_ZOMBIES)
123         ASSERT(!value.isZombie());
124 #endif
125         m_value = JSValue::encode(value);
126     }
127 
128     JSValue get() const
129     {
130         return JSValue::decode(m_value);
131     }
132     void clear() { m_value = JSValue::encode(JSValue()); }
133     void setUndefined() { m_value = JSValue::encode(jsUndefined()); }
134     bool isNumber() const { return get().isNumber(); }
135     bool isObject() const { return get().isObject(); }
136     bool isNull() const { return get().isNull(); }
137     bool isGetterSetter() const { return get().isGetterSetter(); }
138 
139     JSValue* slot()
140     {
141         union {
142             EncodedJSValue* v;
143             JSValue* slot;
144         } u;
145         u.v = &m_value;
146         return u.slot;
147     }
148 
149     typedef JSValue (WriteBarrierBase::*UnspecifiedBoolType);
150     operator UnspecifiedBoolType*() const { return get() ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
151     bool operator!() const { return !get(); }
152 
153 private:
154     EncodedJSValue m_value;
155 };
156 
157 template <typename T> class WriteBarrier : public WriteBarrierBase<T> {
158 public:
159     WriteBarrier()
160     {
161         this->setWithoutWriteBarrier(0);
162     }
163 
164     WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value)
165     {
166         this->set(globalData, owner, value);
167     }
168 };
169 
170 template <> class WriteBarrier<Unknown> : public WriteBarrierBase<Unknown> {
171 public:
172     WriteBarrier()
173     {
174         this->setWithoutWriteBarrier(JSValue());
175     }
176 
177     WriteBarrier(JSGlobalData& globalData, const JSCell* owner, JSValue value)
178     {
179         this->set(globalData, owner, value);
180     }
181 };
182 
183 template <typename U, typename V> inline bool operator==(const WriteBarrierBase<U>& lhs, const WriteBarrierBase<V>& rhs)
184 {
185     return lhs.get() == rhs.get();
186 }
187 
188 } // namespace JSC
189 
190 #endif // WriteBarrier_h
191