]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
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 |