]> git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/Operands.h
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / bytecode / Operands.h
1 /*
2 * Copyright (C) 2011, 2012 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 #ifndef Operands_h
27 #define Operands_h
28
29 #include "CallFrame.h"
30 #include "JSObject.h"
31 #include "ScopeChain.h"
32 #include <wtf/Vector.h>
33
34 namespace JSC {
35
36 // argument 0 is 'this'.
37 inline bool operandIsArgument(int operand) { return operand < 0; }
38 inline int operandToArgument(int operand) { return -operand + CallFrame::thisArgumentOffset(); }
39 inline int argumentToOperand(int argument) { return -argument + CallFrame::thisArgumentOffset(); }
40
41 template<typename T> struct OperandValueTraits;
42
43 template<typename T>
44 struct OperandValueTraits {
45 static T defaultValue() { return T(); }
46 static void dump(const T& value, FILE* out) { value.dump(out); }
47 };
48
49 template<typename T, typename Traits = OperandValueTraits<T> >
50 class Operands {
51 public:
52 Operands() { }
53
54 explicit Operands(size_t numArguments, size_t numLocals)
55 {
56 m_arguments.fill(Traits::defaultValue(), numArguments);
57 m_locals.fill(Traits::defaultValue(), numLocals);
58 }
59
60 size_t numberOfArguments() const { return m_arguments.size(); }
61 size_t numberOfLocals() const { return m_locals.size(); }
62
63 T& argument(size_t idx) { return m_arguments[idx]; }
64 const T& argument(size_t idx) const { return m_arguments[idx]; }
65
66 T& local(size_t idx) { return m_locals[idx]; }
67 const T& local(size_t idx) const { return m_locals[idx]; }
68
69 void ensureLocals(size_t size)
70 {
71 if (size <= m_locals.size())
72 return;
73
74 size_t oldSize = m_locals.size();
75 m_locals.resize(size);
76 for (size_t i = oldSize; i < m_locals.size(); ++i)
77 m_locals[i] = Traits::defaultValue();
78 }
79
80 void setLocal(size_t idx, const T& value)
81 {
82 ensureLocals(idx + 1);
83
84 m_locals[idx] = value;
85 }
86
87 T getLocal(size_t idx)
88 {
89 if (idx >= m_locals.size())
90 return Traits::defaultValue();
91 return m_locals[idx];
92 }
93
94 void setArgumentFirstTime(size_t idx, const T& value)
95 {
96 ASSERT(m_arguments[idx] == Traits::defaultValue());
97 argument(idx) = value;
98 }
99
100 void setLocalFirstTime(size_t idx, const T& value)
101 {
102 ASSERT(idx >= m_locals.size() || m_locals[idx] == Traits::defaultValue());
103 setLocal(idx, value);
104 }
105
106 T& operand(int operand)
107 {
108 if (operandIsArgument(operand)) {
109 int argument = operandToArgument(operand);
110 return m_arguments[argument];
111 }
112
113 return m_locals[operand];
114 }
115
116 const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
117
118 void setOperand(int operand, const T& value)
119 {
120 if (operandIsArgument(operand)) {
121 int argument = operandToArgument(operand);
122 m_arguments[argument] = value;
123 return;
124 }
125
126 setLocal(operand, value);
127 }
128
129 void clear()
130 {
131 for (size_t i = 0; i < m_arguments.size(); ++i)
132 m_arguments[i] = Traits::defaultValue();
133 for (size_t i = 0; i < m_locals.size(); ++i)
134 m_locals[i] = Traits::defaultValue();
135 }
136
137 private:
138 Vector<T, 8> m_arguments;
139 Vector<T, 16> m_locals;
140 };
141
142 template<typename T, typename Traits>
143 void dumpOperands(Operands<T, Traits>& operands, FILE* out)
144 {
145 for (size_t argument = 0; argument < operands.numberOfArguments(); ++argument) {
146 if (argument)
147 fprintf(out, " ");
148 Traits::dump(operands.argument(argument), out);
149 }
150 fprintf(out, " : ");
151 for (size_t local = 0; local < operands.numberOfLocals(); ++local) {
152 if (local)
153 fprintf(out, " ");
154 Traits::dump(operands.local(local), out);
155 }
156 }
157
158 } // namespace JSC
159
160 #endif // Operands_h
161