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 "JSCJSValue.h"
25 #include "PropertyName.h"
26 #include "PropertyOffset.h"
28 #include <wtf/Assertions.h>
37 // Property attributes
40 ReadOnly
= 1 << 1, // property can be only read, not written
41 DontEnum
= 1 << 2, // property doesn't appear in (for .. in ..)
42 DontDelete
= 1 << 3, // property can't be deleted
43 Function
= 1 << 4, // property is a function - only used by static hashtables
44 Accessor
= 1 << 5, // property is a getter/setter
45 CustomAccessor
= 1 << 6,
46 Builtin
= 1 << 7, // property is a builtin function - only used by static hashtables
47 ConstantInteger
= 1 << 8, // property is a constant integer - only used by static hashtables
48 BuiltinOrFunction
= Builtin
| Function
, // helper only used by static hashtables
49 BuiltinOrFunctionOrAccessor
= Builtin
| Function
| Accessor
, // helper only used by static hashtables
50 BuiltinOrFunctionOrAccessorOrConstant
= Builtin
| Function
| Accessor
| ConstantInteger
, // helper only used by static hashtables
61 enum CacheabilityType
{
67 explicit PropertySlot(const JSValue thisValue
)
68 : m_propertyType(TypeUnset
)
69 , m_offset(invalidOffset
)
70 , m_thisValue(thisValue
)
71 , m_watchpointSet(nullptr)
72 , m_cacheability(CachingAllowed
)
76 typedef EncodedJSValue (*GetValueFunc
)(ExecState
*, JSObject
* slotBase
, EncodedJSValue thisValue
, PropertyName
);
78 JSValue
getValue(ExecState
*, PropertyName
) const;
79 JSValue
getValue(ExecState
*, unsigned propertyName
) const;
81 bool isCacheable() const { return m_cacheability
== CachingAllowed
&& m_offset
!= invalidOffset
; }
82 bool isUnset() const { return m_propertyType
== TypeUnset
; }
83 bool isValue() const { return m_propertyType
== TypeValue
; }
84 bool isAccessor() const { return m_propertyType
== TypeGetter
; }
85 bool isCustom() const { return m_propertyType
== TypeCustom
; }
86 bool isCacheableValue() const { return isCacheable() && isValue(); }
87 bool isCacheableGetter() const { return isCacheable() && isAccessor(); }
88 bool isCacheableCustom() const { return isCacheable() && isCustom(); }
92 m_cacheability
= CachingDisallowed
;
95 unsigned attributes() const { return m_attributes
; }
97 PropertyOffset
cachedOffset() const
99 ASSERT(isCacheable());
103 GetterSetter
* getterSetter() const
105 ASSERT(isAccessor());
106 return m_data
.getter
.getterSetter
;
109 GetValueFunc
customGetter() const
111 ASSERT(isCacheableCustom());
112 return m_data
.custom
.getValue
;
115 JSObject
* slotBase() const
117 ASSERT(m_propertyType
!= TypeUnset
);
121 WatchpointSet
* watchpointSet() const
123 return m_watchpointSet
;
126 void setValue(JSObject
* slotBase
, unsigned attributes
, JSValue value
)
129 m_data
.value
= JSValue::encode(value
);
130 m_attributes
= attributes
;
133 m_slotBase
= slotBase
;
134 m_propertyType
= TypeValue
;
135 m_offset
= invalidOffset
;
138 void setValue(JSObject
* slotBase
, unsigned attributes
, JSValue value
, PropertyOffset offset
)
141 m_data
.value
= JSValue::encode(value
);
142 m_attributes
= attributes
;
145 m_slotBase
= slotBase
;
146 m_propertyType
= TypeValue
;
150 void setValue(JSString
*, unsigned attributes
, JSValue value
)
153 m_data
.value
= JSValue::encode(value
);
154 m_attributes
= attributes
;
157 m_propertyType
= TypeValue
;
158 m_offset
= invalidOffset
;
161 void setCustom(JSObject
* slotBase
, unsigned attributes
, GetValueFunc getValue
)
164 m_data
.custom
.getValue
= getValue
;
165 m_attributes
= attributes
;
168 m_slotBase
= slotBase
;
169 m_propertyType
= TypeCustom
;
170 m_offset
= invalidOffset
;
173 void setCacheableCustom(JSObject
* slotBase
, unsigned attributes
, GetValueFunc getValue
)
176 m_data
.custom
.getValue
= getValue
;
177 m_attributes
= attributes
;
180 m_slotBase
= slotBase
;
181 m_propertyType
= TypeCustom
;
182 m_offset
= !invalidOffset
;
185 void setGetterSlot(JSObject
* slotBase
, unsigned attributes
, GetterSetter
* getterSetter
)
187 ASSERT(getterSetter
);
188 m_data
.getter
.getterSetter
= getterSetter
;
189 m_attributes
= attributes
;
192 m_slotBase
= slotBase
;
193 m_propertyType
= TypeGetter
;
194 m_offset
= invalidOffset
;
197 void setCacheableGetterSlot(JSObject
* slotBase
, unsigned attributes
, GetterSetter
* getterSetter
, PropertyOffset offset
)
199 ASSERT(getterSetter
);
200 m_data
.getter
.getterSetter
= getterSetter
;
201 m_attributes
= attributes
;
204 m_slotBase
= slotBase
;
205 m_propertyType
= TypeGetter
;
209 void setThisValue(JSValue thisValue
)
211 m_thisValue
= thisValue
;
216 m_data
.value
= JSValue::encode(jsUndefined());
217 m_attributes
= ReadOnly
| DontDelete
| DontEnum
;
220 m_propertyType
= TypeValue
;
221 m_offset
= invalidOffset
;
224 void setWatchpointSet(WatchpointSet
& set
)
226 m_watchpointSet
= &set
;
230 JS_EXPORT_PRIVATE JSValue
functionGetter(ExecState
*) const;
232 unsigned m_attributes
;
234 EncodedJSValue value
;
236 GetterSetter
* getterSetter
;
239 GetValueFunc getValue
;
243 PropertyType m_propertyType
;
244 PropertyOffset m_offset
;
246 JSObject
* m_slotBase
;
247 WatchpointSet
* m_watchpointSet
;
248 CacheabilityType m_cacheability
;
251 ALWAYS_INLINE JSValue
PropertySlot::getValue(ExecState
* exec
, PropertyName propertyName
) const
253 if (m_propertyType
== TypeValue
)
254 return JSValue::decode(m_data
.value
);
255 if (m_propertyType
== TypeGetter
)
256 return functionGetter(exec
);
257 return JSValue::decode(m_data
.custom
.getValue(exec
, slotBase(), JSValue::encode(m_thisValue
), propertyName
));
260 ALWAYS_INLINE JSValue
PropertySlot::getValue(ExecState
* exec
, unsigned propertyName
) const
262 if (m_propertyType
== TypeValue
)
263 return JSValue::decode(m_data
.value
);
264 if (m_propertyType
== TypeGetter
)
265 return functionGetter(exec
);
266 return JSValue::decode(m_data
.custom
.getValue(exec
, slotBase(), JSValue::encode(m_thisValue
), Identifier::from(exec
, propertyName
)));
271 #endif // PropertySlot_h