]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/PropertySlot.h
JavaScriptCore-1218.33.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 "JSCJSValue.h"
25 #include "PropertyName.h"
26 #include "PropertyOffset.h"
27 #include "Register.h"
28 #include <wtf/Assertions.h>
29 #include <wtf/NotFound.h>
30
31 namespace JSC {
32
33 class ExecState;
34 class JSObject;
35
36 #define JSC_VALUE_MARKER 0
37 #define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2)
38 #define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3)
39
40 class PropertySlot {
41 public:
42 enum CachedPropertyType {
43 Uncacheable,
44 Getter,
45 Custom,
46 Value
47 };
48
49 PropertySlot()
50 : m_cachedPropertyType(Uncacheable)
51 {
52 clearBase();
53 clearOffset();
54 clearValue();
55 }
56
57 explicit PropertySlot(const JSValue base)
58 : m_slotBase(base)
59 , m_cachedPropertyType(Uncacheable)
60 {
61 clearOffset();
62 clearValue();
63 }
64
65 typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, PropertyName);
66 typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned);
67
68 JSValue getValue(ExecState* exec, PropertyName propertyName) const
69 {
70 if (m_getValue == JSC_VALUE_MARKER)
71 return m_value;
72 if (m_getValue == INDEX_GETTER_MARKER)
73 return m_getIndexValue(exec, slotBase(), index());
74 if (m_getValue == GETTER_FUNCTION_MARKER)
75 return functionGetter(exec);
76 return m_getValue(exec, slotBase(), propertyName);
77 }
78
79 JSValue getValue(ExecState* exec, unsigned propertyName) const
80 {
81 if (m_getValue == JSC_VALUE_MARKER)
82 return m_value;
83 if (m_getValue == INDEX_GETTER_MARKER)
84 return m_getIndexValue(exec, m_slotBase, m_data.index);
85 if (m_getValue == GETTER_FUNCTION_MARKER)
86 return functionGetter(exec);
87 return m_getValue(exec, slotBase(), Identifier::from(exec, propertyName));
88 }
89
90 CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; }
91 bool isCacheable() const { return m_cachedPropertyType != Uncacheable; }
92 bool isCacheableValue() const { return m_cachedPropertyType == Value; }
93 PropertyOffset cachedOffset() const
94 {
95 ASSERT(isCacheable());
96 return m_offset;
97 }
98
99 void setValue(JSValue slotBase, JSValue value)
100 {
101 ASSERT(value);
102 clearOffset();
103 m_getValue = JSC_VALUE_MARKER;
104 m_slotBase = slotBase;
105 m_value = value;
106 }
107
108 void setValue(JSValue slotBase, JSValue value, PropertyOffset offset)
109 {
110 ASSERT(value);
111 m_getValue = JSC_VALUE_MARKER;
112 m_slotBase = slotBase;
113 m_value = value;
114 m_offset = offset;
115 m_cachedPropertyType = Value;
116 }
117
118 void setValue(JSValue value)
119 {
120 ASSERT(value);
121 clearBase();
122 clearOffset();
123 m_getValue = JSC_VALUE_MARKER;
124 m_value = value;
125 }
126
127 void setCustom(JSValue slotBase, GetValueFunc getValue)
128 {
129 ASSERT(slotBase);
130 ASSERT(getValue);
131 m_getValue = getValue;
132 m_getIndexValue = 0;
133 m_slotBase = slotBase;
134 }
135
136 void setCacheableCustom(JSValue slotBase, GetValueFunc getValue)
137 {
138 ASSERT(slotBase);
139 ASSERT(getValue);
140 m_getValue = getValue;
141 m_getIndexValue = 0;
142 m_slotBase = slotBase;
143 m_cachedPropertyType = Custom;
144 }
145
146 void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue)
147 {
148 ASSERT(slotBase);
149 ASSERT(getIndexValue);
150 m_getValue = INDEX_GETTER_MARKER;
151 m_getIndexValue = getIndexValue;
152 m_slotBase = slotBase;
153 m_data.index = index;
154 }
155
156 void setGetterSlot(JSObject* getterFunc)
157 {
158 ASSERT(getterFunc);
159 m_thisValue = m_slotBase;
160 m_getValue = GETTER_FUNCTION_MARKER;
161 m_data.getterFunc = getterFunc;
162 }
163
164 void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, PropertyOffset offset)
165 {
166 ASSERT(getterFunc);
167 m_getValue = GETTER_FUNCTION_MARKER;
168 m_thisValue = m_slotBase;
169 m_slotBase = slotBase;
170 m_data.getterFunc = getterFunc;
171 m_offset = offset;
172 m_cachedPropertyType = Getter;
173 }
174
175 void setUndefined()
176 {
177 setValue(jsUndefined());
178 }
179
180 JSValue slotBase() const
181 {
182 return m_slotBase;
183 }
184
185 void setBase(JSValue base)
186 {
187 ASSERT(m_slotBase);
188 ASSERT(base);
189 m_slotBase = base;
190 }
191
192 void clearBase()
193 {
194 #ifndef NDEBUG
195 m_slotBase = JSValue();
196 #endif
197 }
198
199 void clearValue()
200 {
201 #ifndef NDEBUG
202 m_value = JSValue();
203 #endif
204 }
205
206 void clearOffset()
207 {
208 // Clear offset even in release builds, in case this PropertySlot has been used before.
209 // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.)
210 m_offset = invalidOffset;
211 m_cachedPropertyType = Uncacheable;
212 }
213
214 unsigned index() const { return m_data.index; }
215
216 GetValueFunc customGetter() const
217 {
218 ASSERT(m_cachedPropertyType == Custom);
219 return m_getValue;
220 }
221 private:
222 JS_EXPORT_PRIVATE JSValue functionGetter(ExecState*) const;
223
224 GetValueFunc m_getValue;
225 GetIndexValueFunc m_getIndexValue;
226
227 JSValue m_slotBase;
228 union {
229 JSObject* getterFunc;
230 unsigned index;
231 } m_data;
232
233 JSValue m_value;
234 JSValue m_thisValue;
235
236 PropertyOffset m_offset;
237 CachedPropertyType m_cachedPropertyType;
238 };
239
240 } // namespace JSC
241
242 #endif // PropertySlot_h