1/*
2 * Copyright (C) 2013-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#if ENABLE(DFG_JIT)
29
30#include "DFGNodeFlags.h"
31#include "SpeculatedType.h"
32#include <wtf/PrintStream.h>
33
34namespace JSC { namespace DFG {
35
36enum UseKind {
37 // The DFG has 3 representations of values used:
38
39 // 1. The JSValue representation for a JSValue that must be stored in a GP
40 // register (or a GP register pair), and follows rules for boxing and unboxing
41 // that allow the JSValue to be stored as either fully boxed JSValues, or
42 // unboxed Int32, Booleans, Cells, etc. in 32-bit as appropriate.
43 UntypedUse, // UntypedUse must come first (value 0).
44 Int32Use,
45 KnownInt32Use,
46 AnyIntUse,
47 NumberUse,
48 RealNumberUse,
49 BooleanUse,
50 KnownBooleanUse,
51 CellUse,
52 KnownCellUse,
53 CellOrOtherUse,
54 ObjectUse,
55 ArrayUse,
56 FunctionUse,
57 FinalObjectUse,
58 PromiseObjectUse,
59 RegExpObjectUse,
60 ProxyObjectUse,
61 DerivedArrayUse,
62 ObjectOrOtherUse,
63 StringIdentUse,
64 StringUse,
65 StringOrOtherUse,
66 KnownStringUse,
67 KnownPrimitiveUse, // This bizarre type arises for op_strcat, which has a bytecode guarantee that it will only see primitives (i.e. not objects).
68 SymbolUse,
69 BigIntUse,
70 DateObjectUse,
71 MapObjectUse,
72 SetObjectUse,
73 WeakMapObjectUse,
74 WeakSetObjectUse,
75 DataViewObjectUse,
76 StringObjectUse,
77 StringOrStringObjectUse,
78 NotStringVarUse,
79 NotSymbolUse,
80 NotCellUse,
81 KnownOtherUse,
82 OtherUse,
83 MiscUse,
84
85 // 2. The Double representation for an unboxed double value that must be stored
86 // in an FP register.
87 DoubleRepUse,
88 DoubleRepRealUse,
89 DoubleRepAnyIntUse,
90
91 // 3. The Int52 representation for an unboxed integer value that must be stored
92 // in a GP register.
93 Int52RepUse,
94
95 LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
96};
97
98inline SpeculatedType typeFilterFor(UseKind useKind)
99{
100 switch (useKind) {
101 case UntypedUse:
102 return SpecBytecodeTop;
103 case Int32Use:
104 case KnownInt32Use:
105 return SpecInt32Only;
106 case Int52RepUse:
107 return SpecInt52Any;
108 case AnyIntUse:
109 return SpecInt32Only | SpecAnyIntAsDouble;
110 case NumberUse:
111 return SpecBytecodeNumber;
112 case RealNumberUse:
113 return SpecBytecodeRealNumber;
114 case DoubleRepUse:
115 return SpecFullDouble;
116 case DoubleRepRealUse:
117 return SpecDoubleReal;
118 case DoubleRepAnyIntUse:
119 return SpecAnyIntAsDouble;
120 case BooleanUse:
121 case KnownBooleanUse:
122 return SpecBoolean;
123 case CellUse:
124 case KnownCellUse:
125 return SpecCellCheck;
126 case CellOrOtherUse:
127 return SpecCellCheck | SpecOther;
128 case ObjectUse:
129 return SpecObject;
130 case ArrayUse:
131 return SpecArray;
132 case FunctionUse:
133 return SpecFunction;
134 case FinalObjectUse:
135 return SpecFinalObject;
136 case RegExpObjectUse:
137 return SpecRegExpObject;
138 case ProxyObjectUse:
139 return SpecProxyObject;
140 case DerivedArrayUse:
141 return SpecDerivedArray;
142 case ObjectOrOtherUse:
143 return SpecObject | SpecOther;
144 case StringIdentUse:
145 return SpecStringIdent;
146 case StringUse:
147 case KnownStringUse:
148 return SpecString;
149 case StringOrOtherUse:
150 return SpecString | SpecOther;
151 case KnownPrimitiveUse:
152 return SpecHeapTop & ~SpecObject;
153 case SymbolUse:
154 return SpecSymbol;
155 case BigIntUse:
156 return SpecBigInt;
157 case PromiseObjectUse:
158 return SpecPromiseObject;
159 case DateObjectUse:
160 return SpecDateObject;
161 case MapObjectUse:
162 return SpecMapObject;
163 case SetObjectUse:
164 return SpecSetObject;
165 case WeakMapObjectUse:
166 return SpecWeakMapObject;
167 case WeakSetObjectUse:
168 return SpecWeakSetObject;
169 case DataViewObjectUse:
170 return SpecDataViewObject;
171 case StringObjectUse:
172 return SpecStringObject;
173 case StringOrStringObjectUse:
174 return SpecString | SpecStringObject;
175 case NotStringVarUse:
176 return ~SpecStringVar;
177 case NotSymbolUse:
178 return ~SpecSymbol;
179 case NotCellUse:
180 return ~SpecCellCheck;
181 case KnownOtherUse:
182 case OtherUse:
183 return SpecOther;
184 case MiscUse:
185 return SpecMisc;
186 default:
187 RELEASE_ASSERT_NOT_REACHED();
188 return SpecFullTop;
189 }
190}
191
192inline bool shouldNotHaveTypeCheck(UseKind kind)
193{
194 switch (kind) {
195 case UntypedUse:
196 case KnownInt32Use:
197 case KnownCellUse:
198 case KnownStringUse:
199 case KnownPrimitiveUse:
200 case KnownBooleanUse:
201 case KnownOtherUse:
202 case Int52RepUse:
203 case DoubleRepUse:
204 return true;
205 default:
206 return false;
207 }
208}
209
210inline bool mayHaveTypeCheck(UseKind kind)
211{
212 return !shouldNotHaveTypeCheck(kind);
213}
214
215inline bool isNumerical(UseKind kind)
216{
217 switch (kind) {
218 case Int32Use:
219 case KnownInt32Use:
220 case NumberUse:
221 case RealNumberUse:
222 case Int52RepUse:
223 case DoubleRepUse:
224 case DoubleRepRealUse:
225 case AnyIntUse:
226 case DoubleRepAnyIntUse:
227 return true;
228 default:
229 return false;
230 }
231}
232
233inline bool isDouble(UseKind kind)
234{
235 switch (kind) {
236 case DoubleRepUse:
237 case DoubleRepRealUse:
238 case DoubleRepAnyIntUse:
239 return true;
240 default:
241 return false;
242 }
243}
244
245// Returns true if the use kind only admits cells, and is therefore appropriate for
246// SpeculateCellOperand in the DFG or lowCell() in the FTL.
247inline bool isCell(UseKind kind)
248{
249 switch (kind) {
250 case CellUse:
251 case KnownCellUse:
252 case ObjectUse:
253 case ArrayUse:
254 case FunctionUse:
255 case FinalObjectUse:
256 case RegExpObjectUse:
257 case PromiseObjectUse:
258 case ProxyObjectUse:
259 case DerivedArrayUse:
260 case StringIdentUse:
261 case StringUse:
262 case KnownStringUse:
263 case SymbolUse:
264 case BigIntUse:
265 case StringObjectUse:
266 case StringOrStringObjectUse:
267 case DateObjectUse:
268 case MapObjectUse:
269 case SetObjectUse:
270 case WeakMapObjectUse:
271 case WeakSetObjectUse:
272 case DataViewObjectUse:
273 return true;
274 default:
275 return false;
276 }
277}
278
279// Returns true if we've already guaranteed the type
280inline bool alreadyChecked(UseKind kind, SpeculatedType type)
281{
282 return !(type & ~typeFilterFor(kind));
283}
284
285inline UseKind useKindForResult(NodeFlags result)
286{
287 ASSERT(!(result & ~NodeResultMask));
288 switch (result) {
289 case NodeResultInt52:
290 return Int52RepUse;
291 case NodeResultDouble:
292 return DoubleRepUse;
293 default:
294 return UntypedUse;
295 }
296}
297
298inline bool checkMayCrashIfInputIsEmpty(UseKind kind)
299{
300#if USE(JSVALUE64)
301 switch (kind) {
302 case UntypedUse:
303 case Int32Use:
304 case KnownInt32Use:
305 case AnyIntUse:
306 case NumberUse:
307 case BooleanUse:
308 case KnownBooleanUse:
309 case CellUse:
310 case KnownCellUse:
311 case CellOrOtherUse:
312 case KnownOtherUse:
313 case OtherUse:
314 case MiscUse:
315 case NotCellUse:
316 return false;
317 default:
318 return true;
319 }
320#else
321 UNUSED_PARAM(kind);
322 return true;
323#endif
324}
325
326} } // namespace JSC::DFG
327
328namespace WTF {
329
330void printInternal(PrintStream&, JSC::DFG::UseKind);
331
332} // namespace WTF
333
334#endif // ENABLE(DFG_JIT)
335