2 * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
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.
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.
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.
21 #ifndef PropertySlot_h
22 #define PropertySlot_h
24 #include "Identifier.h"
27 #include <wtf/Assertions.h>
28 #include <wtf/NotFound.h>
35 #define JSC_VALUE_SLOT_MARKER 0
36 #define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
37 #define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2)
38 #define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3)
42 enum CachedPropertyType
{
50 : m_cachedPropertyType(Uncacheable
)
57 explicit PropertySlot(const JSValue base
)
59 , m_cachedPropertyType(Uncacheable
)
65 typedef JSValue (*GetValueFunc
)(ExecState
*, JSValue slotBase
, const Identifier
&);
66 typedef JSValue (*GetIndexValueFunc
)(ExecState
*, JSValue slotBase
, unsigned);
68 JSValue
getValue(ExecState
* exec
, const Identifier
& propertyName
) const
70 if (m_getValue
== JSC_VALUE_SLOT_MARKER
)
71 return *m_data
.valueSlot
;
72 if (m_getValue
== JSC_REGISTER_SLOT_MARKER
)
73 return (*m_data
.registerSlot
).jsValue();
74 if (m_getValue
== INDEX_GETTER_MARKER
)
75 return m_getIndexValue(exec
, slotBase(), index());
76 if (m_getValue
== GETTER_FUNCTION_MARKER
)
77 return functionGetter(exec
);
78 return m_getValue(exec
, slotBase(), propertyName
);
81 JSValue
getValue(ExecState
* exec
, unsigned propertyName
) const
83 if (m_getValue
== JSC_VALUE_SLOT_MARKER
)
84 return *m_data
.valueSlot
;
85 if (m_getValue
== JSC_REGISTER_SLOT_MARKER
)
86 return (*m_data
.registerSlot
).jsValue();
87 if (m_getValue
== INDEX_GETTER_MARKER
)
88 return m_getIndexValue(exec
, m_slotBase
, m_data
.index
);
89 if (m_getValue
== GETTER_FUNCTION_MARKER
)
90 return functionGetter(exec
);
91 return m_getValue(exec
, slotBase(), Identifier::from(exec
, propertyName
));
94 CachedPropertyType
cachedPropertyType() const { return m_cachedPropertyType
; }
95 bool isCacheable() const { return m_cachedPropertyType
!= Uncacheable
; }
96 bool isCacheableValue() const { return m_cachedPropertyType
== Value
; }
97 size_t cachedOffset() const
99 ASSERT(isCacheable());
103 void setValueSlot(JSValue
* valueSlot
)
108 m_getValue
= JSC_VALUE_SLOT_MARKER
;
109 m_data
.valueSlot
= valueSlot
;
112 void setValueSlot(JSValue slotBase
, JSValue
* valueSlot
)
115 m_getValue
= JSC_VALUE_SLOT_MARKER
;
116 m_slotBase
= slotBase
;
117 m_data
.valueSlot
= valueSlot
;
120 void setValueSlot(JSValue slotBase
, JSValue
* valueSlot
, size_t offset
)
123 m_getValue
= JSC_VALUE_SLOT_MARKER
;
124 m_slotBase
= slotBase
;
125 m_data
.valueSlot
= valueSlot
;
127 m_cachedPropertyType
= Value
;
130 void setValue(JSValue value
)
135 m_getValue
= JSC_VALUE_SLOT_MARKER
;
137 m_data
.valueSlot
= &m_value
;
140 void setRegisterSlot(Register
* registerSlot
)
142 ASSERT(registerSlot
);
145 m_getValue
= JSC_REGISTER_SLOT_MARKER
;
146 m_data
.registerSlot
= registerSlot
;
149 void setCustom(JSValue slotBase
, GetValueFunc getValue
)
153 m_getValue
= getValue
;
155 m_slotBase
= slotBase
;
158 void setCacheableCustom(JSValue slotBase
, GetValueFunc getValue
)
162 m_getValue
= getValue
;
164 m_slotBase
= slotBase
;
165 m_cachedPropertyType
= Custom
;
168 void setCustomIndex(JSValue slotBase
, unsigned index
, GetIndexValueFunc getIndexValue
)
171 ASSERT(getIndexValue
);
172 m_getValue
= INDEX_GETTER_MARKER
;
173 m_getIndexValue
= getIndexValue
;
174 m_slotBase
= slotBase
;
175 m_data
.index
= index
;
178 void setGetterSlot(JSObject
* getterFunc
)
181 m_thisValue
= m_slotBase
;
182 m_getValue
= GETTER_FUNCTION_MARKER
;
183 m_data
.getterFunc
= getterFunc
;
186 void setCacheableGetterSlot(JSValue slotBase
, JSObject
* getterFunc
, unsigned offset
)
189 m_getValue
= GETTER_FUNCTION_MARKER
;
190 m_thisValue
= m_slotBase
;
191 m_slotBase
= slotBase
;
192 m_data
.getterFunc
= getterFunc
;
194 m_cachedPropertyType
= Getter
;
199 setValue(jsUndefined());
202 JSValue
slotBase() const
207 void setBase(JSValue base
)
217 m_slotBase
= JSValue();
230 // Clear offset even in release builds, in case this PropertySlot has been used before.
231 // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.)
233 m_cachedPropertyType
= Uncacheable
;
236 unsigned index() const { return m_data
.index
; }
238 JSValue
thisValue() const { return m_thisValue
; }
240 GetValueFunc
customGetter() const
242 ASSERT(m_cachedPropertyType
== Custom
);
246 JSValue
functionGetter(ExecState
*) const;
248 GetValueFunc m_getValue
;
249 GetIndexValueFunc m_getIndexValue
;
253 JSObject
* getterFunc
;
255 Register
* registerSlot
;
263 CachedPropertyType m_cachedPropertyType
;
268 #endif // PropertySlot_h