1/*
2 * Copyright (C) 2008, 2009 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/Assertions.h>
34#include <wtf/FastAllocBase.h>
35#include <wtf/VectorTraits.h>
36
37namespace JSC {
38
39    class Arguments;
40    class CodeBlock;
41    class ExecState;
42    class JSActivation;
43    class JSFunction;
44    class JSPropertyNameIterator;
45    class ScopeChainNode;
46
47    struct Instruction;
48
49    typedef ExecState CallFrame;
50
51    class Register : public WTF::FastAllocBase {
52    public:
53        Register();
54
55        Register(const JSValue&);
56        Register& operator=(const JSValue&);
57        JSValue jsValue() const;
58
59        Register& operator=(JSActivation*);
60        Register& operator=(CallFrame*);
61        Register& operator=(CodeBlock*);
62        Register& operator=(JSFunction*);
63        Register& operator=(JSPropertyNameIterator*);
64        Register& operator=(ScopeChainNode*);
65        Register& operator=(Instruction*);
66
67        int32_t i() const;
68        JSActivation* activation() const;
69        Arguments* arguments() const;
70        CallFrame* callFrame() const;
71        CodeBlock* codeBlock() const;
72        JSFunction* function() const;
73        JSPropertyNameIterator* propertyNameIterator() const;
74        ScopeChainNode* scopeChain() const;
75        Instruction* vPC() const;
76
77        static Register withInt(int32_t i)
78        {
79            Register r;
80            r.u.i = i;
81            return r;
82        }
83
84    private:
85        union {
86            int32_t i;
87            EncodedJSValue value;
88
89            JSActivation* activation;
90            CallFrame* callFrame;
91            CodeBlock* codeBlock;
92            JSFunction* function;
93            JSPropertyNameIterator* propertyNameIterator;
94            ScopeChainNode* scopeChain;
95            Instruction* vPC;
96        } u;
97    };
98
99    ALWAYS_INLINE Register::Register()
100    {
101#ifndef NDEBUG
102        *this = JSValue();
103#endif
104    }
105
106    ALWAYS_INLINE Register::Register(const JSValue& v)
107    {
108#if ENABLE(JSC_ZOMBIES)
109        ASSERT(!v.isZombie());
110#endif
111        u.value = JSValue::encode(v);
112    }
113
114    ALWAYS_INLINE Register& Register::operator=(const JSValue& v)
115    {
116#if ENABLE(JSC_ZOMBIES)
117        ASSERT(!v.isZombie());
118#endif
119        u.value = JSValue::encode(v);
120        return *this;
121    }
122
123    ALWAYS_INLINE JSValue Register::jsValue() const
124    {
125        return JSValue::decode(u.value);
126    }
127
128    // Interpreter functions
129
130    ALWAYS_INLINE Register& Register::operator=(JSActivation* activation)
131    {
132        u.activation = activation;
133        return *this;
134    }
135
136    ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame)
137    {
138        u.callFrame = callFrame;
139        return *this;
140    }
141
142    ALWAYS_INLINE Register& Register::operator=(CodeBlock* codeBlock)
143    {
144        u.codeBlock = codeBlock;
145        return *this;
146    }
147
148    ALWAYS_INLINE Register& Register::operator=(JSFunction* function)
149    {
150        u.function = function;
151        return *this;
152    }
153
154    ALWAYS_INLINE Register& Register::operator=(Instruction* vPC)
155    {
156        u.vPC = vPC;
157        return *this;
158    }
159
160    ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
161    {
162        u.scopeChain = scopeChain;
163        return *this;
164    }
165
166    ALWAYS_INLINE Register& Register::operator=(JSPropertyNameIterator* propertyNameIterator)
167    {
168        u.propertyNameIterator = propertyNameIterator;
169        return *this;
170    }
171
172    ALWAYS_INLINE int32_t Register::i() const
173    {
174        return u.i;
175    }
176
177    ALWAYS_INLINE JSActivation* Register::activation() const
178    {
179        return u.activation;
180    }
181
182    ALWAYS_INLINE CallFrame* Register::callFrame() const
183    {
184        return u.callFrame;
185    }
186
187    ALWAYS_INLINE CodeBlock* Register::codeBlock() const
188    {
189        return u.codeBlock;
190    }
191
192    ALWAYS_INLINE JSFunction* Register::function() const
193    {
194        return u.function;
195    }
196
197    ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
198    {
199        return u.propertyNameIterator;
200    }
201
202    ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
203    {
204        return u.scopeChain;
205    }
206
207    ALWAYS_INLINE Instruction* Register::vPC() const
208    {
209        return u.vPC;
210    }
211
212} // namespace JSC
213
214namespace WTF {
215
216    template<> struct VectorTraits<JSC::Register> : VectorTraitsBase<true, JSC::Register> { };
217
218} // namespace WTF
219
220#endif // Register_h
221