]> git.saurik.com Git - apple/javascriptcore.git/blob - interpreter/Register.h
JavaScriptCore-525.tar.gz
[apple/javascriptcore.git] / interpreter / Register.h
1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef Register_h
30 #define Register_h
31
32 #include "JSValue.h"
33 #include <wtf/VectorTraits.h>
34
35 namespace JSC {
36
37 class Arguments;
38 class CodeBlock;
39 class ExecState;
40 class JSActivation;
41 class JSFunction;
42 class JSPropertyNameIterator;
43 class ScopeChainNode;
44
45 struct Instruction;
46
47 typedef ExecState CallFrame;
48
49 class Register {
50 public:
51 Register();
52 Register(JSValuePtr);
53
54 JSValuePtr jsValue(CallFrame*) const;
55 JSValuePtr getJSValue() const;
56
57 bool marked() const;
58 void mark();
59
60 private:
61 friend class ExecState;
62 friend class Interpreter;
63
64 // Only CallFrame and Interpreter should use these functions.
65
66 Register(intptr_t);
67
68 Register(JSActivation*);
69 Register(Arguments*);
70 Register(CallFrame*);
71 Register(CodeBlock*);
72 Register(JSFunction*);
73 Register(JSPropertyNameIterator*);
74 Register(ScopeChainNode*);
75 Register(Instruction*);
76
77 intptr_t i() const;
78 void* v() const;
79
80 JSActivation* activation() const;
81 Arguments* arguments() const;
82 CallFrame* callFrame() const;
83 CodeBlock* codeBlock() const;
84 JSFunction* function() const;
85 JSPropertyNameIterator* propertyNameIterator() const;
86 ScopeChainNode* scopeChain() const;
87 Instruction* vPC() const;
88
89 union {
90 intptr_t i;
91 void* v;
92 JSValueEncodedAsPointer* value;
93
94 JSActivation* activation;
95 Arguments* arguments;
96 CallFrame* callFrame;
97 CodeBlock* codeBlock;
98 JSFunction* function;
99 JSPropertyNameIterator* propertyNameIterator;
100 ScopeChainNode* scopeChain;
101 Instruction* vPC;
102 } u;
103
104 #ifndef NDEBUG
105 enum {
106 EmptyType,
107
108 IntType,
109 ValueType,
110
111 ActivationType,
112 ArgumentsType,
113 CallFrameType,
114 CodeBlockType,
115 FunctionType,
116 InstructionType,
117 PropertyNameIteratorType,
118 RegisterType,
119 ScopeChainNodeType
120 } m_type;
121 #endif
122 };
123
124 #ifndef NDEBUG
125 #define SET_TYPE(type) m_type = (type)
126 // FIXME: The CTI code to put value into registers doesn't set m_type.
127 // Once it does, we can turn this assertion back on.
128 #define ASSERT_TYPE(type)
129 #else
130 #define SET_TYPE(type)
131 #define ASSERT_TYPE(type)
132 #endif
133
134 ALWAYS_INLINE Register::Register()
135 {
136 #ifndef NDEBUG
137 SET_TYPE(EmptyType);
138 u.value = JSValuePtr::encode(noValue());
139 #endif
140 }
141
142 ALWAYS_INLINE Register::Register(JSValuePtr v)
143 {
144 SET_TYPE(ValueType);
145 u.value = JSValuePtr::encode(v);
146 }
147
148 // This function is scaffolding for legacy clients. It will eventually go away.
149 ALWAYS_INLINE JSValuePtr Register::jsValue(CallFrame*) const
150 {
151 // Once registers hold doubles, this function will allocate a JSValue*
152 // if the register doesn't hold one already.
153 ASSERT_TYPE(ValueType);
154 return JSValuePtr::decode(u.value);
155 }
156
157 ALWAYS_INLINE JSValuePtr Register::getJSValue() const
158 {
159 ASSERT_TYPE(JSValueType);
160 return JSValuePtr::decode(u.value);
161 }
162
163 ALWAYS_INLINE bool Register::marked() const
164 {
165 return getJSValue().marked();
166 }
167
168 ALWAYS_INLINE void Register::mark()
169 {
170 getJSValue().mark();
171 }
172
173 // Interpreter functions
174
175 ALWAYS_INLINE Register::Register(Arguments* arguments)
176 {
177 SET_TYPE(ArgumentsType);
178 u.arguments = arguments;
179 }
180
181 ALWAYS_INLINE Register::Register(JSActivation* activation)
182 {
183 SET_TYPE(ActivationType);
184 u.activation = activation;
185 }
186
187 ALWAYS_INLINE Register::Register(CallFrame* callFrame)
188 {
189 SET_TYPE(CallFrameType);
190 u.callFrame = callFrame;
191 }
192
193 ALWAYS_INLINE Register::Register(CodeBlock* codeBlock)
194 {
195 SET_TYPE(CodeBlockType);
196 u.codeBlock = codeBlock;
197 }
198
199 ALWAYS_INLINE Register::Register(JSFunction* function)
200 {
201 SET_TYPE(FunctionType);
202 u.function = function;
203 }
204
205 ALWAYS_INLINE Register::Register(Instruction* vPC)
206 {
207 SET_TYPE(InstructionType);
208 u.vPC = vPC;
209 }
210
211 ALWAYS_INLINE Register::Register(ScopeChainNode* scopeChain)
212 {
213 SET_TYPE(ScopeChainNodeType);
214 u.scopeChain = scopeChain;
215 }
216
217 ALWAYS_INLINE Register::Register(JSPropertyNameIterator* propertyNameIterator)
218 {
219 SET_TYPE(PropertyNameIteratorType);
220 u.propertyNameIterator = propertyNameIterator;
221 }
222
223 ALWAYS_INLINE Register::Register(intptr_t i)
224 {
225 SET_TYPE(IntType);
226 u.i = i;
227 }
228
229 ALWAYS_INLINE intptr_t Register::i() const
230 {
231 ASSERT_TYPE(IntType);
232 return u.i;
233 }
234
235 ALWAYS_INLINE void* Register::v() const
236 {
237 return u.v;
238 }
239
240 ALWAYS_INLINE JSActivation* Register::activation() const
241 {
242 ASSERT_TYPE(ActivationType);
243 return u.activation;
244 }
245
246 ALWAYS_INLINE Arguments* Register::arguments() const
247 {
248 ASSERT_TYPE(ArgumentsType);
249 return u.arguments;
250 }
251
252 ALWAYS_INLINE CallFrame* Register::callFrame() const
253 {
254 ASSERT_TYPE(CallFrameType);
255 return u.callFrame;
256 }
257
258 ALWAYS_INLINE CodeBlock* Register::codeBlock() const
259 {
260 ASSERT_TYPE(CodeBlockType);
261 return u.codeBlock;
262 }
263
264 ALWAYS_INLINE JSFunction* Register::function() const
265 {
266 ASSERT_TYPE(FunctionType);
267 return u.function;
268 }
269
270 ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
271 {
272 ASSERT_TYPE(PropertyNameIteratorType);
273 return u.propertyNameIterator;
274 }
275
276 ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
277 {
278 ASSERT_TYPE(ScopeChainNodeType);
279 return u.scopeChain;
280 }
281
282 ALWAYS_INLINE Instruction* Register::vPC() const
283 {
284 ASSERT_TYPE(InstructionType);
285 return u.vPC;
286 }
287
288 #undef SET_TYPE
289 #undef ASSERT_TYPE
290
291 } // namespace JSC
292
293 namespace WTF {
294
295 template<> struct VectorTraits<JSC::Register> : VectorTraitsBase<true, JSC::Register> { };
296
297 } // namespace WTF
298
299 #endif // Register_h