]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/PropertySlot.h
JavaScriptCore-903.5.tar.gz
[apple/javascriptcore.git] / runtime / PropertySlot.h
1 /*
2 * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21 #ifndef PropertySlot_h
22 #define PropertySlot_h
23
24 #include "Identifier.h"
25 #include "JSValue.h"
26 #include "Register.h"
27 #include <wtf/Assertions.h>
28 #include <wtf/NotFound.h>
29
30 namespace JSC {
31
32 class ExecState;
33 class JSObject;
34
35 #define JSC_VALUE_MARKER 0
36 #define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2)
37 #define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3)
38
39 class PropertySlot {
40 public:
41 enum CachedPropertyType {
42 Uncacheable,
43 Getter,
44 Custom,
45 Value
46 };
47
48 PropertySlot()
49 : m_cachedPropertyType(Uncacheable)
50 {
51 clearBase();
52 clearOffset();
53 clearValue();
54 }
55
56 explicit PropertySlot(const JSValue base)
57 : m_slotBase(base)
58 , m_cachedPropertyType(Uncacheable)
59 {
60 clearOffset();
61 clearValue();
62 }
63
64 typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, const Identifier&);
65 typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned);
66
67 JSValue getValue(ExecState* exec, const Identifier& propertyName) const
68 {
69 if (m_getValue == JSC_VALUE_MARKER)
70 return m_value;
71 if (m_getValue == INDEX_GETTER_MARKER)
72 return m_getIndexValue(exec, slotBase(), index());
73 if (m_getValue == GETTER_FUNCTION_MARKER)
74 return functionGetter(exec);
75 return m_getValue(exec, slotBase(), propertyName);
76 }
77
78 JSValue getValue(ExecState* exec, unsigned propertyName) const
79 {
80 if (m_getValue == JSC_VALUE_MARKER)
81 return m_value;
82 if (m_getValue == INDEX_GETTER_MARKER)
83 return m_getIndexValue(exec, m_slotBase, m_data.index);
84 if (m_getValue == GETTER_FUNCTION_MARKER)
85 return functionGetter(exec);
86 return m_getValue(exec, slotBase(), Identifier::from(exec, propertyName));
87 }
88
89 CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; }
90 bool isCacheable() const { return m_cachedPropertyType != Uncacheable; }
91 bool isCacheableValue() const { return m_cachedPropertyType == Value; }
92 size_t cachedOffset() const
93 {
94 ASSERT(isCacheable());
95 return m_offset;
96 }
97
98 void setValue(JSValue slotBase, JSValue value)
99 {
100 ASSERT(value);
101 clearOffset();
102 m_getValue = JSC_VALUE_MARKER;
103 m_slotBase = slotBase;
104 m_value = value;
105 }
106
107 void setValue(JSValue slotBase, JSValue value, size_t offset)
108 {
109 ASSERT(value);
110 m_getValue = JSC_VALUE_MARKER;
111 m_slotBase = slotBase;
112 m_value = value;
113 m_offset = offset;
114 m_cachedPropertyType = Value;
115 }
116
117 void setValue(JSValue value)
118 {
119 ASSERT(value);
120 clearBase();
121 clearOffset();
122 m_getValue = JSC_VALUE_MARKER;
123 m_value = value;
124 }
125
126 void setCustom(JSValue slotBase, GetValueFunc getValue)
127 {
128 ASSERT(slotBase);
129 ASSERT(getValue);
130 m_getValue = getValue;
131 m_getIndexValue = 0;
132 m_slotBase = slotBase;
133 }
134
135 void setCacheableCustom(JSValue slotBase, GetValueFunc getValue)
136 {
137 ASSERT(slotBase);
138 ASSERT(getValue);
139 m_getValue = getValue;
140 m_getIndexValue = 0;
141 m_slotBase = slotBase;
142 m_cachedPropertyType = Custom;
143 }
144
145 void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue)
146 {
147 ASSERT(slotBase);
148 ASSERT(getIndexValue);
149 m_getValue = INDEX_GETTER_MARKER;
150 m_getIndexValue = getIndexValue;
151 m_slotBase = slotBase;
152 m_data.index = index;
153 }
154
155 void setGetterSlot(JSObject* getterFunc)
156 {
157 ASSERT(getterFunc);
158 m_thisValue = m_slotBase;
159 m_getValue = GETTER_FUNCTION_MARKER;
160 m_data.getterFunc = getterFunc;
161 }
162
163 void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset)
164 {
165 ASSERT(getterFunc);
166 m_getValue = GETTER_FUNCTION_MARKER;
167 m_thisValue = m_slotBase;
168 m_slotBase = slotBase;
169 m_data.getterFunc = getterFunc;
170 m_offset = offset;
171 m_cachedPropertyType = Getter;
172 }
173
174 void setUndefined()
175 {
176 setValue(jsUndefined());
177 }
178
179 JSValue slotBase() const
180 {
181 return m_slotBase;
182 }
183
184 void setBase(JSValue base)
185 {
186 ASSERT(m_slotBase);
187 ASSERT(base);
188 m_slotBase = base;
189 }
190
191 void clearBase()
192 {
193 #ifndef NDEBUG
194 m_slotBase = JSValue();
195 #endif
196 }
197
198 void clearValue()
199 {
200 #ifndef NDEBUG
201 m_value = JSValue();
202 #endif
203 }
204
205 void clearOffset()
206 {
207 // Clear offset even in release builds, in case this PropertySlot has been used before.
208 // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.)
209 m_offset = 0;
210 m_cachedPropertyType = Uncacheable;
211 }
212
213 unsigned index() const { return m_data.index; }
214
215 JSValue thisValue() const { return m_thisValue; }
216
217 GetValueFunc customGetter() const
218 {
219 ASSERT(m_cachedPropertyType == Custom);
220 return m_getValue;
221 }
222 private:
223 JSValue functionGetter(ExecState*) const;
224
225 GetValueFunc m_getValue;
226 GetIndexValueFunc m_getIndexValue;
227
228 JSValue m_slotBase;
229 union {
230 JSObject* getterFunc;
231 unsigned index;
232 } m_data;
233
234 JSValue m_value;
235 JSValue m_thisValue;
236
237 size_t m_offset;
238 CachedPropertyType m_cachedPropertyType;
239 };
240
241 } // namespace JSC
242
243 #endif // PropertySlot_h