]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/VarOffset.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / VarOffset.h
CommitLineData
ed1e77d3
A
1/*
2 * Copyright (C) 2015 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 VarOffset_h
27#define VarOffset_h
28
29#include "DirectArgumentsOffset.h"
30#include "ScopeOffset.h"
31#include "VirtualRegister.h"
32#include <wtf/HashMap.h>
33
34namespace JSC {
35
36enum class VarKind : uint8_t {
37 Invalid,
38 Scope,
39 Stack,
40 DirectArgument
41};
42
43class VarOffset {
44public:
45 VarOffset()
46 : m_kind(VarKind::Invalid)
47 , m_offset(UINT_MAX)
48 {
49 }
50
51 VarOffset(WTF::HashTableDeletedValueType)
52 : m_kind(VarKind::Invalid)
53 , m_offset(0)
54 {
55 }
56
57 explicit VarOffset(VirtualRegister stackOffset)
58 {
59 if (!stackOffset.isValid()) {
60 m_kind = VarKind::Invalid;
61 m_offset = UINT_MAX;
62 } else {
63 m_kind = VarKind::Stack;
64 m_offset = stackOffset.offset();
65 }
66 }
67
68 explicit VarOffset(ScopeOffset scopeOffset)
69 {
70 if (!scopeOffset) {
71 m_kind = VarKind::Invalid;
72 m_offset = UINT_MAX;
73 } else {
74 m_kind = VarKind::Scope;
75 m_offset = scopeOffset.offset();
76 }
77 }
78
79 explicit VarOffset(DirectArgumentsOffset capturedArgumentsOffset)
80 {
81 if (!capturedArgumentsOffset) {
82 m_kind = VarKind::Invalid;
83 m_offset = UINT_MAX;
84 } else {
85 m_kind = VarKind::DirectArgument;
86 m_offset = capturedArgumentsOffset.offset();
87 }
88 }
89
90 static VarOffset assemble(VarKind kind, unsigned offset)
91 {
92 VarOffset result;
93 result.m_kind = kind;
94 result.m_offset = offset;
95 result.checkSanity();
96 return result;
97 }
98
99 bool isValid() const
100 {
101 return m_kind != VarKind::Invalid;
102 }
103
104 bool operator!() const
105 {
106 return !isValid();
107 }
108
109 VarKind kind() const { return m_kind; }
110
111 bool isStack() const
112 {
113 return m_kind == VarKind::Stack;
114 }
115
116 bool isScope() const
117 {
118 return m_kind == VarKind::Scope;
119 }
120
121 bool isDirectArgument() const
122 {
123 return m_kind == VarKind::DirectArgument;
124 }
125
126 VirtualRegister stackOffsetUnchecked() const
127 {
128 if (!isStack())
129 return VirtualRegister();
130 return VirtualRegister(m_offset);
131 }
132
133 ScopeOffset scopeOffsetUnchecked() const
134 {
135 if (!isScope())
136 return ScopeOffset();
137 return ScopeOffset(m_offset);
138 }
139
140 DirectArgumentsOffset capturedArgumentsOffsetUnchecked() const
141 {
142 if (!isDirectArgument())
143 return DirectArgumentsOffset();
144 return DirectArgumentsOffset(m_offset);
145 }
146
147 VirtualRegister stackOffset() const
148 {
149 ASSERT(isStack());
150 return VirtualRegister(m_offset);
151 }
152
153 ScopeOffset scopeOffset() const
154 {
155 ASSERT(isScope());
156 return ScopeOffset(m_offset);
157 }
158
159 DirectArgumentsOffset capturedArgumentsOffset() const
160 {
161 ASSERT(isDirectArgument());
162 return DirectArgumentsOffset(m_offset);
163 }
164
165 unsigned rawOffset() const
166 {
167 ASSERT(isValid());
168 return m_offset;
169 }
170
171 void checkSanity() const
172 {
173 if (ASSERT_DISABLED)
174 return;
175
176 switch (m_kind) {
177 case VarKind::Invalid:
178 ASSERT(m_offset == UINT_MAX);
179 return;
180 case VarKind::Scope:
181 ASSERT(scopeOffset());
182 return;
183 case VarKind::Stack:
184 ASSERT(stackOffset().isValid());
185 return;
186 case VarKind::DirectArgument:
187 ASSERT(capturedArgumentsOffset());
188 return;
189 }
190
191 ASSERT_NOT_REACHED();
192 }
193
194 bool operator==(const VarOffset& other) const
195 {
196 return m_kind == other.m_kind
197 && m_offset == other.m_offset;
198 }
199
200 bool operator!=(const VarOffset& other) const
201 {
202 return !(*this == other);
203 }
204
205 unsigned hash() const
206 {
207 return WTF::IntHash<unsigned>::hash((static_cast<unsigned>(m_kind) << 20) + m_offset);
208 }
209
210 bool isHashTableDeletedValue() const
211 {
212 return m_kind == VarKind::Invalid && !m_offset;
213 }
214
215 void dump(PrintStream&) const;
216
217private:
218 VarKind m_kind;
219 unsigned m_offset;
220};
221
222struct VarOffsetHash {
223 static unsigned hash(const VarOffset& key) { return key.hash(); }
224 static bool equal(const VarOffset& a, const VarOffset& b) { return a == b; }
225 static const bool safeToCompareToEmptyOrDeleted = true;
226};
227
228} // namespace JSC
229
230namespace WTF {
231
232void printInternal(PrintStream&, JSC::VarKind);
233
234template<typename T> struct DefaultHash;
235template<> struct DefaultHash<JSC::VarOffset> {
236 typedef JSC::VarOffsetHash Hash;
237};
238
239template<typename T> struct HashTraits;
240template<> struct HashTraits<JSC::VarOffset> : SimpleClassHashTraits<JSC::VarOffset> {
241 static const bool emptyValueIsZero = false;
242};
243
244} // namespace WTF
245
246#endif // VarOffset_h
247