]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/PropertySlot.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / runtime / PropertySlot.h
CommitLineData
9dae56ea
A
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
93a37866
A
24#include "JSCJSValue.h"
25#include "PropertyName.h"
26#include "PropertyOffset.h"
9dae56ea
A
27#include "Register.h"
28#include <wtf/Assertions.h>
29#include <wtf/NotFound.h>
30
31namespace JSC {
32
33 class ExecState;
34 class JSObject;
35
14957cd0 36#define JSC_VALUE_MARKER 0
4e4e5a6f
A
37#define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2)
38#define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3)
9dae56ea
A
39
40 class PropertySlot {
41 public:
4e4e5a6f
A
42 enum CachedPropertyType {
43 Uncacheable,
44 Getter,
45 Custom,
46 Value
47 };
48
9dae56ea 49 PropertySlot()
4e4e5a6f 50 : m_cachedPropertyType(Uncacheable)
9dae56ea
A
51 {
52 clearBase();
ba379fdc 53 clearOffset();
9dae56ea
A
54 clearValue();
55 }
56
ba379fdc 57 explicit PropertySlot(const JSValue base)
9dae56ea 58 : m_slotBase(base)
4e4e5a6f 59 , m_cachedPropertyType(Uncacheable)
9dae56ea 60 {
ba379fdc 61 clearOffset();
9dae56ea
A
62 clearValue();
63 }
64
93a37866 65 typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, PropertyName);
4e4e5a6f 66 typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned);
9dae56ea 67
93a37866 68 JSValue getValue(ExecState* exec, PropertyName propertyName) const
9dae56ea 69 {
14957cd0
A
70 if (m_getValue == JSC_VALUE_MARKER)
71 return m_value;
4e4e5a6f
A
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);
9dae56ea
A
77 }
78
ba379fdc 79 JSValue getValue(ExecState* exec, unsigned propertyName) const
9dae56ea 80 {
14957cd0
A
81 if (m_getValue == JSC_VALUE_MARKER)
82 return m_value;
4e4e5a6f
A
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));
9dae56ea
A
88 }
89
4e4e5a6f
A
90 CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; }
91 bool isCacheable() const { return m_cachedPropertyType != Uncacheable; }
92 bool isCacheableValue() const { return m_cachedPropertyType == Value; }
93a37866 93 PropertyOffset cachedOffset() const
9dae56ea
A
94 {
95 ASSERT(isCacheable());
96 return m_offset;
97 }
98
14957cd0 99 void setValue(JSValue slotBase, JSValue value)
9dae56ea 100 {
14957cd0 101 ASSERT(value);
ba379fdc 102 clearOffset();
14957cd0 103 m_getValue = JSC_VALUE_MARKER;
9dae56ea 104 m_slotBase = slotBase;
14957cd0 105 m_value = value;
9dae56ea
A
106 }
107
93a37866 108 void setValue(JSValue slotBase, JSValue value, PropertyOffset offset)
9dae56ea 109 {
14957cd0
A
110 ASSERT(value);
111 m_getValue = JSC_VALUE_MARKER;
9dae56ea 112 m_slotBase = slotBase;
14957cd0 113 m_value = value;
9dae56ea 114 m_offset = offset;
4e4e5a6f 115 m_cachedPropertyType = Value;
9dae56ea 116 }
14957cd0 117
ba379fdc 118 void setValue(JSValue value)
9dae56ea
A
119 {
120 ASSERT(value);
9dae56ea 121 clearBase();
ba379fdc 122 clearOffset();
14957cd0 123 m_getValue = JSC_VALUE_MARKER;
9dae56ea 124 m_value = value;
9dae56ea
A
125 }
126
ba379fdc 127 void setCustom(JSValue slotBase, GetValueFunc getValue)
9dae56ea
A
128 {
129 ASSERT(slotBase);
130 ASSERT(getValue);
131 m_getValue = getValue;
4e4e5a6f 132 m_getIndexValue = 0;
9dae56ea
A
133 m_slotBase = slotBase;
134 }
4e4e5a6f
A
135
136 void setCacheableCustom(JSValue slotBase, GetValueFunc getValue)
9dae56ea
A
137 {
138 ASSERT(slotBase);
139 ASSERT(getValue);
140 m_getValue = getValue;
4e4e5a6f
A
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;
9dae56ea
A
152 m_slotBase = slotBase;
153 m_data.index = index;
154 }
4e4e5a6f 155
9dae56ea
A
156 void setGetterSlot(JSObject* getterFunc)
157 {
158 ASSERT(getterFunc);
4e4e5a6f
A
159 m_thisValue = m_slotBase;
160 m_getValue = GETTER_FUNCTION_MARKER;
9dae56ea
A
161 m_data.getterFunc = getterFunc;
162 }
4e4e5a6f 163
93a37866 164 void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, PropertyOffset offset)
4e4e5a6f
A
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
9dae56ea
A
175 void setUndefined()
176 {
9dae56ea
A
177 setValue(jsUndefined());
178 }
179
ba379fdc 180 JSValue slotBase() const
9dae56ea 181 {
9dae56ea
A
182 return m_slotBase;
183 }
184
ba379fdc 185 void setBase(JSValue base)
9dae56ea
A
186 {
187 ASSERT(m_slotBase);
188 ASSERT(base);
189 m_slotBase = base;
190 }
191
192 void clearBase()
193 {
194#ifndef NDEBUG
ba379fdc 195 m_slotBase = JSValue();
9dae56ea
A
196#endif
197 }
198
199 void clearValue()
200 {
201#ifndef NDEBUG
ba379fdc 202 m_value = JSValue();
9dae56ea
A
203#endif
204 }
205
ba379fdc
A
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.)
93a37866 210 m_offset = invalidOffset;
4e4e5a6f 211 m_cachedPropertyType = Uncacheable;
ba379fdc
A
212 }
213
9dae56ea
A
214 unsigned index() const { return m_data.index; }
215
4e4e5a6f
A
216 GetValueFunc customGetter() const
217 {
218 ASSERT(m_cachedPropertyType == Custom);
219 return m_getValue;
220 }
9dae56ea 221 private:
6fe7ccc8 222 JS_EXPORT_PRIVATE JSValue functionGetter(ExecState*) const;
9dae56ea
A
223
224 GetValueFunc m_getValue;
4e4e5a6f 225 GetIndexValueFunc m_getIndexValue;
9dae56ea 226
ba379fdc 227 JSValue m_slotBase;
9dae56ea
A
228 union {
229 JSObject* getterFunc;
9dae56ea
A
230 unsigned index;
231 } m_data;
232
ba379fdc 233 JSValue m_value;
4e4e5a6f 234 JSValue m_thisValue;
9dae56ea 235
93a37866 236 PropertyOffset m_offset;
4e4e5a6f 237 CachedPropertyType m_cachedPropertyType;
9dae56ea
A
238 };
239
240} // namespace JSC
241
242#endif // PropertySlot_h