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