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