[BigInt] Add ValueBitRShift into DFG
[WebKit-https.git] / Source / JavaScriptCore / bytecode / Opcode.h
1 /*
2  * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #pragma once
31
32 #include "Bytecodes.h"
33 #include "LLIntOpcode.h"
34
35 #include <algorithm>
36 #include <string.h>
37
38 #include <wtf/Assertions.h>
39
40 namespace JSC {
41
42 #define FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, extension__) \
43     FOR_EACH_BYTECODE_ID(macro) \
44     extension__
45
46 #define FOR_EACH_CORE_OPCODE_ID(macro) \
47     FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, /* No extension */ )
48
49 #define FOR_EACH_OPCODE_ID(macro) \
50     FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION( \
51         macro, \
52         FOR_EACH_LLINT_OPCODE_EXTENSION(macro) \
53     )
54
55
56 const int maxOpcodeLength = 40;
57 #if ENABLE(C_LOOP)
58 const int numOpcodeIDs = NUMBER_OF_BYTECODE_IDS + NUMBER_OF_CLOOP_BYTECODE_HELPER_IDS + NUMBER_OF_BYTECODE_HELPER_IDS;
59 #else
60 const int numOpcodeIDs = NUMBER_OF_BYTECODE_IDS + NUMBER_OF_BYTECODE_HELPER_IDS;
61 #endif
62
63 #define OPCODE_ID_ENUM(opcode, length) opcode,
64     enum OpcodeID : unsigned { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) };
65 #undef OPCODE_ID_ENUM
66
67 #if ENABLE(C_LOOP) && !HAVE(COMPUTED_GOTO)
68
69 #define OPCODE_ID_ENUM(opcode, length) opcode##_wide16 = numOpcodeIDs + opcode,
70     enum OpcodeIDWide16 : unsigned { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) };
71 #undef OPCODE_ID_ENUM
72
73 #define OPCODE_ID_ENUM(opcode, length) opcode##_wide32 = numOpcodeIDs * 2 + opcode,
74     enum OpcodeIDWide32 : unsigned { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) };
75 #undef OPCODE_ID_ENUM
76 #endif
77
78 extern const unsigned opcodeLengths[];
79
80 #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
81     FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS);
82 #undef OPCODE_ID_LENGTHS
83
84 #define FOR_EACH_OPCODE_WITH_VALUE_PROFILE(macro) \
85     macro(OpCallVarargs) \
86     macro(OpTailCallVarargs) \
87     macro(OpTailCallForwardArguments) \
88     macro(OpConstructVarargs) \
89     macro(OpGetByVal) \
90     macro(OpGetDirectPname) \
91     macro(OpGetById) \
92     macro(OpGetByIdWithThis) \
93     macro(OpTryGetById) \
94     macro(OpGetByIdDirect) \
95     macro(OpGetByValWithThis) \
96     macro(OpGetFromArguments) \
97     macro(OpToNumber) \
98     macro(OpToObject) \
99     macro(OpGetArgument) \
100     macro(OpGetInternalField) \
101     macro(OpToThis) \
102     macro(OpCall) \
103     macro(OpTailCall) \
104     macro(OpCallEval) \
105     macro(OpConstruct) \
106     macro(OpGetFromScope) \
107     macro(OpBitand) \
108     macro(OpBitor) \
109     macro(OpBitnot) \
110     macro(OpBitxor) \
111     macro(OpLshift) \
112     macro(OpRshift) \
113
114 #define FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(macro) \
115     macro(OpHasIndexedProperty) \
116     macro(OpCallVarargs) \
117     macro(OpTailCallVarargs) \
118     macro(OpTailCallForwardArguments) \
119     macro(OpConstructVarargs) \
120     macro(OpGetByVal) \
121     macro(OpInByVal) \
122     macro(OpPutByVal) \
123     macro(OpPutByValDirect) \
124
125 #define FOR_EACH_OPCODE_WITH_ARRAY_ALLOCATION_PROFILE(macro) \
126     macro(OpNewArray) \
127     macro(OpNewArrayWithSize) \
128     macro(OpNewArrayBuffer) \
129
130 #define FOR_EACH_OPCODE_WITH_OBJECT_ALLOCATION_PROFILE(macro) \
131     macro(OpNewObject) \
132
133 #define FOR_EACH_OPCODE_WITH_LLINT_CALL_LINK_INFO(macro) \
134     macro(OpCall) \
135     macro(OpTailCall) \
136     macro(OpCallEval) \
137     macro(OpConstruct) \
138
139 IGNORE_WARNINGS_BEGIN("type-limits")
140
141 #define VERIFY_OPCODE_ID(id, size) COMPILE_ASSERT(id <= numOpcodeIDs, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
142     FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
143 #undef VERIFY_OPCODE_ID
144
145 IGNORE_WARNINGS_END
146
147 #if ENABLE(COMPUTED_GOTO_OPCODES)
148 typedef void* Opcode;
149 #else
150 typedef OpcodeID Opcode;
151 #endif
152
153 extern const char* const opcodeNames[];
154
155 #if ENABLE(OPCODE_STATS)
156
157 struct OpcodeStats {
158     OpcodeStats();
159     ~OpcodeStats();
160     static long long opcodeCounts[numOpcodeIDs];
161     static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
162     static int lastOpcode;
163     
164     static void recordInstruction(int opcode);
165     static void resetLastInstruction();
166 };
167
168 #endif
169
170 inline bool isBranch(OpcodeID opcodeID)
171 {
172     switch (opcodeID) {
173     case op_jmp:
174     case op_jtrue:
175     case op_jfalse:
176     case op_jeq_null:
177     case op_jneq_null:
178     case op_jundefined_or_null:
179     case op_jnundefined_or_null:
180     case op_jneq_ptr:
181     case op_jless:
182     case op_jlesseq:
183     case op_jgreater:
184     case op_jgreatereq:
185     case op_jnless:
186     case op_jnlesseq:
187     case op_jngreater:
188     case op_jngreatereq:
189     case op_jeq:
190     case op_jneq:
191     case op_jstricteq:
192     case op_jnstricteq:
193     case op_jbelow:
194     case op_jbeloweq:
195     case op_switch_imm:
196     case op_switch_char:
197     case op_switch_string:
198         return true;
199     default:
200         return false;
201     }
202 }
203
204 inline bool isUnconditionalBranch(OpcodeID opcodeID)
205 {
206     switch (opcodeID) {
207     case op_jmp:
208         return true;
209     default:
210         return false;
211     }
212 }
213
214 inline bool isTerminal(OpcodeID opcodeID)
215 {
216     switch (opcodeID) {
217     case op_ret:
218     case op_end:
219     case op_unreachable:
220         return true;
221     default:
222         return false;
223     }
224 }
225
226 inline bool isThrow(OpcodeID opcodeID)
227 {
228     switch (opcodeID) {
229     case op_throw:
230     case op_throw_static_error:
231         return true;
232     default:
233         return false;
234     }
235 }
236
237 unsigned metadataSize(OpcodeID);
238 unsigned metadataAlignment(OpcodeID);
239
240 } // namespace JSC
241
242 namespace WTF {
243
244 class PrintStream;
245
246 void printInternal(PrintStream&, JSC::OpcodeID);
247
248 } // namespace WTF