Remove excessive headers from JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / bytecode / Operands.h
1 /*
2  * Copyright (C) 2011, 2012, 2013, 2015, 2016 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #include "CallFrame.h"
29 #include "VirtualRegister.h"
30
31 #include <wtf/PrintStream.h>
32 #include <wtf/Vector.h>
33
34 namespace JSC {
35
36 template<typename T> struct OperandValueTraits;
37
38 enum OperandKind { ArgumentOperand, LocalOperand };
39
40 enum OperandsLikeTag { OperandsLike };
41
42 template<typename T>
43 class Operands {
44 public:
45     Operands() { }
46     
47     explicit Operands(size_t numArguments, size_t numLocals)
48     {
49         if (WTF::VectorTraits<T>::needsInitialization) {
50             m_arguments.resize(numArguments);
51             m_locals.resize(numLocals);
52         } else {
53             m_arguments.fill(T(), numArguments);
54             m_locals.fill(T(), numLocals);
55         }
56     }
57
58     explicit Operands(size_t numArguments, size_t numLocals, const T& initialValue)
59     {
60         m_arguments.fill(initialValue, numArguments);
61         m_locals.fill(initialValue, numLocals);
62     }
63     
64     template<typename U>
65     explicit Operands(OperandsLikeTag, const Operands<U>& other)
66     {
67         m_arguments.fill(T(), other.numberOfArguments());
68         m_locals.fill(T(), other.numberOfLocals());
69     }
70     
71     size_t numberOfArguments() const { return m_arguments.size(); }
72     size_t numberOfLocals() const { return m_locals.size(); }
73     
74     T& argument(size_t idx) { return m_arguments[idx]; }
75     const T& argument(size_t idx) const { return m_arguments[idx]; }
76     
77     T& local(size_t idx) { return m_locals[idx]; }
78     const T& local(size_t idx) const { return m_locals[idx]; }
79     
80     template<OperandKind operandKind>
81     size_t sizeFor() const
82     {
83         if (operandKind == ArgumentOperand)
84             return numberOfArguments();
85         return numberOfLocals();
86     }
87     template<OperandKind operandKind>
88     T& atFor(size_t idx)
89     {
90         if (operandKind == ArgumentOperand)
91             return argument(idx);
92         return local(idx);
93     }
94     template<OperandKind operandKind>
95     const T& atFor(size_t idx) const
96     {
97         if (operandKind == ArgumentOperand)
98             return argument(idx);
99         return local(idx);
100     }
101     
102     void ensureLocals(size_t size)
103     {
104         if (size <= m_locals.size())
105             return;
106
107         size_t oldSize = m_locals.size();
108         m_locals.resize(size);
109         if (!WTF::VectorTraits<T>::needsInitialization) {
110             for (size_t i = oldSize; i < m_locals.size(); ++i)
111                 m_locals[i] = T();
112         }
113     }
114
115     void ensureLocals(size_t size, const T& ensuredValue)
116     {
117         if (size <= m_locals.size())
118             return;
119
120         size_t oldSize = m_locals.size();
121         m_locals.resize(size);
122         for (size_t i = oldSize; i < m_locals.size(); ++i)
123             m_locals[i] = ensuredValue;
124     }
125     
126     void setLocal(size_t idx, const T& value)
127     {
128         ensureLocals(idx + 1);
129         
130         m_locals[idx] = value;
131     }
132     
133     T getLocal(size_t idx)
134     {
135         if (idx >= m_locals.size())
136             return T();
137         return m_locals[idx];
138     }
139     
140     void setArgumentFirstTime(size_t idx, const T& value)
141     {
142         ASSERT(m_arguments[idx] == T());
143         argument(idx) = value;
144     }
145     
146     void setLocalFirstTime(size_t idx, const T& value)
147     {
148         ASSERT(idx >= m_locals.size() || m_locals[idx] == T());
149         setLocal(idx, value);
150     }
151     
152     T& operand(int operand)
153     {
154         if (operandIsArgument(operand)) {
155             int argument = VirtualRegister(operand).toArgument();
156             return m_arguments[argument];
157         }
158
159         return m_locals[VirtualRegister(operand).toLocal()];
160     }
161
162     T& operand(VirtualRegister virtualRegister)
163     {
164         return operand(virtualRegister.offset());
165     }
166
167     const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
168     const T& operand(VirtualRegister operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
169     
170     bool hasOperand(int operand) const
171     {
172         if (operandIsArgument(operand))
173             return true;
174         return static_cast<size_t>(VirtualRegister(operand).toLocal()) < numberOfLocals();
175     }
176     bool hasOperand(VirtualRegister reg) const
177     {
178         return hasOperand(reg.offset());
179     }
180     
181     void setOperand(int operand, const T& value)
182     {
183         if (operandIsArgument(operand)) {
184             int argument = VirtualRegister(operand).toArgument();
185             m_arguments[argument] = value;
186             return;
187         }
188         
189         setLocal(VirtualRegister(operand).toLocal(), value);
190     }
191     
192     void setOperand(VirtualRegister virtualRegister, const T& value)
193     {
194         setOperand(virtualRegister.offset(), value);
195     }
196
197     size_t size() const { return numberOfArguments() + numberOfLocals(); }
198     const T& at(size_t index) const
199     {
200         if (index < numberOfArguments())
201             return m_arguments[index];
202         return m_locals[index - numberOfArguments()];
203     }
204     T& at(size_t index)
205     {
206         if (index < numberOfArguments())
207             return m_arguments[index];
208         return m_locals[index - numberOfArguments()];
209     }
210     const T& operator[](size_t index) const { return at(index); }
211     T& operator[](size_t index) { return at(index); }
212
213     bool isArgument(size_t index) const { return index < numberOfArguments(); }
214     bool isVariable(size_t index) const { return !isArgument(index); }
215     int argumentForIndex(size_t index) const
216     {
217         return index;
218     }
219     int variableForIndex(size_t index) const
220     {
221         return index - m_arguments.size();
222     }
223     int operandForIndex(size_t index) const
224     {
225         if (index < numberOfArguments())
226             return virtualRegisterForArgument(index).offset();
227         return virtualRegisterForLocal(index - numberOfArguments()).offset();
228     }
229     VirtualRegister virtualRegisterForIndex(size_t index) const
230     {
231         return VirtualRegister(operandForIndex(index));
232     }
233     size_t indexForOperand(int operand) const
234     {
235         if (operandIsArgument(operand))
236             return static_cast<size_t>(VirtualRegister(operand).toArgument());
237         return static_cast<size_t>(VirtualRegister(operand).toLocal()) + numberOfArguments();
238     }
239     size_t indexForOperand(VirtualRegister reg) const
240     {
241         return indexForOperand(reg.offset());
242     }
243     
244     void setOperandFirstTime(int operand, const T& value)
245     {
246         if (operandIsArgument(operand)) {
247             setArgumentFirstTime(VirtualRegister(operand).toArgument(), value);
248             return;
249         }
250         
251         setLocalFirstTime(VirtualRegister(operand).toLocal(), value);
252     }
253     
254     void fill(T value)
255     {
256         for (size_t i = 0; i < m_arguments.size(); ++i)
257             m_arguments[i] = value;
258         for (size_t i = 0; i < m_locals.size(); ++i)
259             m_locals[i] = value;
260     }
261     
262     void clear()
263     {
264         fill(T());
265     }
266     
267     bool operator==(const Operands& other) const
268     {
269         ASSERT(numberOfArguments() == other.numberOfArguments());
270         ASSERT(numberOfLocals() == other.numberOfLocals());
271         
272         return m_arguments == other.m_arguments && m_locals == other.m_locals;
273     }
274     
275     void dumpInContext(PrintStream& out, DumpContext* context) const;
276     void dump(PrintStream& out) const;
277     
278 private:
279     Vector<T, 8> m_arguments;
280     Vector<T, 16> m_locals;
281 };
282
283 } // namespace JSC