• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
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:
PropertySlot()40         PropertySlot()
41         {
42             clearBase();
43             clearOffset();
44             clearValue();
45         }
46 
PropertySlot(const JSValue base)47         explicit PropertySlot(const JSValue base)
48             : m_slotBase(base)
49         {
50             clearOffset();
51             clearValue();
52         }
53 
54         typedef JSValue (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
55 
getValue(ExecState * exec,const Identifier & propertyName)56         JSValue getValue(ExecState* exec, const Identifier& propertyName) const
57         {
58             if (m_getValue == JSC_VALUE_SLOT_MARKER)
59                 return *m_data.valueSlot;
60             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
61                 return (*m_data.registerSlot).jsValue();
62             return m_getValue(exec, propertyName, *this);
63         }
64 
getValue(ExecState * exec,unsigned propertyName)65         JSValue getValue(ExecState* exec, unsigned propertyName) const
66         {
67             if (m_getValue == JSC_VALUE_SLOT_MARKER)
68                 return *m_data.valueSlot;
69             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
70                 return (*m_data.registerSlot).jsValue();
71             return m_getValue(exec, Identifier::from(exec, propertyName), *this);
72         }
73 
isCacheable()74         bool isCacheable() const { return m_offset != WTF::notFound; }
cachedOffset()75         size_t cachedOffset() const
76         {
77             ASSERT(isCacheable());
78             return m_offset;
79         }
80 
setValueSlot(JSValue * valueSlot)81         void setValueSlot(JSValue* valueSlot)
82         {
83             ASSERT(valueSlot);
84             clearBase();
85             clearOffset();
86             m_getValue = JSC_VALUE_SLOT_MARKER;
87             m_data.valueSlot = valueSlot;
88         }
89 
setValueSlot(JSValue slotBase,JSValue * valueSlot)90         void setValueSlot(JSValue slotBase, JSValue* valueSlot)
91         {
92             ASSERT(valueSlot);
93             m_getValue = JSC_VALUE_SLOT_MARKER;
94             m_slotBase = slotBase;
95             m_data.valueSlot = valueSlot;
96         }
97 
setValueSlot(JSValue slotBase,JSValue * valueSlot,size_t offset)98         void setValueSlot(JSValue slotBase, JSValue* valueSlot, size_t offset)
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 
setValue(JSValue value)107         void setValue(JSValue value)
108         {
109             ASSERT(value);
110             clearBase();
111             clearOffset();
112             m_getValue = JSC_VALUE_SLOT_MARKER;
113             m_value = value;
114             m_data.valueSlot = &m_value;
115         }
116 
setRegisterSlot(Register * registerSlot)117         void setRegisterSlot(Register* registerSlot)
118         {
119             ASSERT(registerSlot);
120             clearBase();
121             clearOffset();
122             m_getValue = JSC_REGISTER_SLOT_MARKER;
123             m_data.registerSlot = registerSlot;
124         }
125 
setCustom(JSValue slotBase,GetValueFunc getValue)126         void setCustom(JSValue slotBase, GetValueFunc getValue)
127         {
128             ASSERT(slotBase);
129             ASSERT(getValue);
130             m_getValue = getValue;
131             m_slotBase = slotBase;
132         }
133 
setCustomIndex(JSValue slotBase,unsigned index,GetValueFunc getValue)134         void setCustomIndex(JSValue slotBase, unsigned index, GetValueFunc getValue)
135         {
136             ASSERT(slotBase);
137             ASSERT(getValue);
138             m_getValue = getValue;
139             m_slotBase = slotBase;
140             m_data.index = index;
141         }
142 
setGetterSlot(JSObject * getterFunc)143         void setGetterSlot(JSObject* getterFunc)
144         {
145             ASSERT(getterFunc);
146             m_getValue = functionGetter;
147             m_data.getterFunc = getterFunc;
148         }
149 
setUndefined()150         void setUndefined()
151         {
152             setValue(jsUndefined());
153         }
154 
slotBase()155         JSValue slotBase() const
156         {
157             return m_slotBase;
158         }
159 
setBase(JSValue base)160         void setBase(JSValue base)
161         {
162             ASSERT(m_slotBase);
163             ASSERT(base);
164             m_slotBase = base;
165         }
166 
clearBase()167         void clearBase()
168         {
169 #ifndef NDEBUG
170             m_slotBase = JSValue();
171 #endif
172         }
173 
clearValue()174         void clearValue()
175         {
176 #ifndef NDEBUG
177             m_value = JSValue();
178 #endif
179         }
180 
clearOffset()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 
index()188         unsigned index() const { return m_data.index; }
189 
190     private:
191         static JSValue functionGetter(ExecState*, const Identifier&, const PropertySlot&);
192 
193         GetValueFunc m_getValue;
194 
195         JSValue m_slotBase;
196         union {
197             JSObject* getterFunc;
198             JSValue* valueSlot;
199             Register* registerSlot;
200             unsigned index;
201         } m_data;
202 
203         JSValue m_value;
204 
205         size_t m_offset;
206     };
207 
208 } // namespace JSC
209 
210 #endif // PropertySlot_h
211