]>
Commit | Line | Data |
---|---|---|
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 | ||
30 | namespace JSC { | |
31 | ||
32 | class ExecState; | |
33 | class JSObject; | |
34 | ||
35 | #define JSC_VALUE_SLOT_MARKER 0 | |
36 | #define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1) | |
37 | ||
38 | class PropertySlot { | |
39 | public: | |
40 | PropertySlot() | |
9dae56ea A |
41 | { |
42 | clearBase(); | |
ba379fdc | 43 | clearOffset(); |
9dae56ea A |
44 | clearValue(); |
45 | } | |
46 | ||
ba379fdc | 47 | explicit PropertySlot(const JSValue base) |
9dae56ea | 48 | : m_slotBase(base) |
9dae56ea | 49 | { |
ba379fdc | 50 | clearOffset(); |
9dae56ea A |
51 | clearValue(); |
52 | } | |
53 | ||
ba379fdc | 54 | typedef JSValue (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&); |
9dae56ea | 55 | |
ba379fdc | 56 | JSValue getValue(ExecState* exec, const Identifier& propertyName) const |
9dae56ea A |
57 | { |
58 | if (m_getValue == JSC_VALUE_SLOT_MARKER) | |
59 | return *m_data.valueSlot; | |
60 | if (m_getValue == JSC_REGISTER_SLOT_MARKER) | |
ba379fdc | 61 | return (*m_data.registerSlot).jsValue(); |
9dae56ea A |
62 | return m_getValue(exec, propertyName, *this); |
63 | } | |
64 | ||
ba379fdc | 65 | JSValue getValue(ExecState* exec, unsigned propertyName) const |
9dae56ea A |
66 | { |
67 | if (m_getValue == JSC_VALUE_SLOT_MARKER) | |
68 | return *m_data.valueSlot; | |
69 | if (m_getValue == JSC_REGISTER_SLOT_MARKER) | |
ba379fdc | 70 | return (*m_data.registerSlot).jsValue(); |
9dae56ea A |
71 | return m_getValue(exec, Identifier::from(exec, propertyName), *this); |
72 | } | |
73 | ||
74 | bool isCacheable() const { return m_offset != WTF::notFound; } | |
75 | size_t cachedOffset() const | |
76 | { | |
77 | ASSERT(isCacheable()); | |
78 | return m_offset; | |
79 | } | |
80 | ||
ba379fdc | 81 | void setValueSlot(JSValue* valueSlot) |
9dae56ea A |
82 | { |
83 | ASSERT(valueSlot); | |
9dae56ea | 84 | clearBase(); |
ba379fdc A |
85 | clearOffset(); |
86 | m_getValue = JSC_VALUE_SLOT_MARKER; | |
9dae56ea A |
87 | m_data.valueSlot = valueSlot; |
88 | } | |
89 | ||
ba379fdc | 90 | void setValueSlot(JSValue slotBase, JSValue* valueSlot) |
9dae56ea A |
91 | { |
92 | ASSERT(valueSlot); | |
93 | m_getValue = JSC_VALUE_SLOT_MARKER; | |
94 | m_slotBase = slotBase; | |
95 | m_data.valueSlot = valueSlot; | |
96 | } | |
97 | ||
ba379fdc | 98 | void setValueSlot(JSValue slotBase, JSValue* valueSlot, size_t offset) |
9dae56ea A |
99 | { |
100 | ASSERT(valueSlot); | |
101 | m_getValue = JSC_VALUE_SLOT_MARKER; | |
102 | m_slotBase = slotBase; | |
103 | m_data.valueSlot = valueSlot; | |
104 | m_offset = offset; | |
105 | } | |
106 | ||
ba379fdc | 107 | void setValue(JSValue value) |
9dae56ea A |
108 | { |
109 | ASSERT(value); | |
9dae56ea | 110 | clearBase(); |
ba379fdc A |
111 | clearOffset(); |
112 | m_getValue = JSC_VALUE_SLOT_MARKER; | |
9dae56ea A |
113 | m_value = value; |
114 | m_data.valueSlot = &m_value; | |
115 | } | |
116 | ||
117 | void setRegisterSlot(Register* registerSlot) | |
118 | { | |
119 | ASSERT(registerSlot); | |
9dae56ea | 120 | clearBase(); |
ba379fdc A |
121 | clearOffset(); |
122 | m_getValue = JSC_REGISTER_SLOT_MARKER; | |
9dae56ea A |
123 | m_data.registerSlot = registerSlot; |
124 | } | |
125 | ||
ba379fdc | 126 | void setCustom(JSValue slotBase, GetValueFunc getValue) |
9dae56ea A |
127 | { |
128 | ASSERT(slotBase); | |
129 | ASSERT(getValue); | |
130 | m_getValue = getValue; | |
131 | m_slotBase = slotBase; | |
132 | } | |
133 | ||
ba379fdc | 134 | void setCustomIndex(JSValue slotBase, unsigned index, GetValueFunc getValue) |
9dae56ea A |
135 | { |
136 | ASSERT(slotBase); | |
137 | ASSERT(getValue); | |
138 | m_getValue = getValue; | |
139 | m_slotBase = slotBase; | |
140 | m_data.index = index; | |
141 | } | |
142 | ||
143 | void setGetterSlot(JSObject* getterFunc) | |
144 | { | |
145 | ASSERT(getterFunc); | |
146 | m_getValue = functionGetter; | |
147 | m_data.getterFunc = getterFunc; | |
148 | } | |
149 | ||
150 | void setUndefined() | |
151 | { | |
9dae56ea A |
152 | setValue(jsUndefined()); |
153 | } | |
154 | ||
ba379fdc | 155 | JSValue slotBase() const |
9dae56ea | 156 | { |
9dae56ea A |
157 | return m_slotBase; |
158 | } | |
159 | ||
ba379fdc | 160 | void setBase(JSValue base) |
9dae56ea A |
161 | { |
162 | ASSERT(m_slotBase); | |
163 | ASSERT(base); | |
164 | m_slotBase = base; | |
165 | } | |
166 | ||
167 | void clearBase() | |
168 | { | |
169 | #ifndef NDEBUG | |
ba379fdc | 170 | m_slotBase = JSValue(); |
9dae56ea A |
171 | #endif |
172 | } | |
173 | ||
174 | void clearValue() | |
175 | { | |
176 | #ifndef NDEBUG | |
ba379fdc | 177 | m_value = JSValue(); |
9dae56ea A |
178 | #endif |
179 | } | |
180 | ||
ba379fdc A |
181 | void clearOffset() |
182 | { | |
183 | // Clear offset even in release builds, in case this PropertySlot has been used before. | |
184 | // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.) | |
185 | m_offset = WTF::notFound; | |
186 | } | |
187 | ||
9dae56ea A |
188 | unsigned index() const { return m_data.index; } |
189 | ||
190 | private: | |
ba379fdc | 191 | static JSValue functionGetter(ExecState*, const Identifier&, const PropertySlot&); |
9dae56ea A |
192 | |
193 | GetValueFunc m_getValue; | |
194 | ||
ba379fdc | 195 | JSValue m_slotBase; |
9dae56ea A |
196 | union { |
197 | JSObject* getterFunc; | |
ba379fdc | 198 | JSValue* valueSlot; |
9dae56ea A |
199 | Register* registerSlot; |
200 | unsigned index; | |
201 | } m_data; | |
202 | ||
ba379fdc | 203 | JSValue m_value; |
9dae56ea A |
204 | |
205 | size_t m_offset; | |
206 | }; | |
207 | ||
208 | } // namespace JSC | |
209 | ||
210 | #endif // PropertySlot_h |