• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_INTERPRETER_BYTECODES_H_
6 #define V8_INTERPRETER_BYTECODES_H_
7 
8 #include <cstdint>
9 #include <iosfwd>
10 #include <string>
11 #include <vector>
12 
13 #include "src/globals.h"
14 #include "src/interpreter/bytecode-operands.h"
15 
16 // This interface and it's implementation are independent of the
17 // libv8_base library as they are used by the interpreter and the
18 // standalone mkpeephole table generator program.
19 
20 namespace v8 {
21 namespace internal {
22 namespace interpreter {
23 
24 // The list of bytecodes which are interpreted by the interpreter.
25 // Format is V(<bytecode>, <accumulator_use>, <operands>).
26 #define BYTECODE_LIST(V)                                                       \
27   /* Extended width operands */                                                \
28   V(Wide, AccumulatorUse::kNone)                                               \
29   V(ExtraWide, AccumulatorUse::kNone)                                          \
30                                                                                \
31   /* Debug Breakpoints - one for each possible size of unscaled bytecodes */   \
32   /* and one for each operand widening prefix bytecode                    */   \
33   V(DebugBreakWide, AccumulatorUse::kReadWrite)                                \
34   V(DebugBreakExtraWide, AccumulatorUse::kReadWrite)                           \
35   V(DebugBreak0, AccumulatorUse::kReadWrite)                                   \
36   V(DebugBreak1, AccumulatorUse::kReadWrite, OperandType::kReg)                \
37   V(DebugBreak2, AccumulatorUse::kReadWrite, OperandType::kReg,                \
38     OperandType::kReg)                                                         \
39   V(DebugBreak3, AccumulatorUse::kReadWrite, OperandType::kReg,                \
40     OperandType::kReg, OperandType::kReg)                                      \
41   V(DebugBreak4, AccumulatorUse::kReadWrite, OperandType::kReg,                \
42     OperandType::kReg, OperandType::kReg, OperandType::kReg)                   \
43   V(DebugBreak5, AccumulatorUse::kReadWrite, OperandType::kRuntimeId,          \
44     OperandType::kReg, OperandType::kReg)                                      \
45   V(DebugBreak6, AccumulatorUse::kReadWrite, OperandType::kRuntimeId,          \
46     OperandType::kReg, OperandType::kReg, OperandType::kReg)                   \
47                                                                                \
48   /* Loading the accumulator */                                                \
49   V(LdaZero, AccumulatorUse::kWrite)                                           \
50   V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm)                         \
51   V(LdaUndefined, AccumulatorUse::kWrite)                                      \
52   V(LdaNull, AccumulatorUse::kWrite)                                           \
53   V(LdaTheHole, AccumulatorUse::kWrite)                                        \
54   V(LdaTrue, AccumulatorUse::kWrite)                                           \
55   V(LdaFalse, AccumulatorUse::kWrite)                                          \
56   V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx)                    \
57                                                                                \
58   /* Globals */                                                                \
59   V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx, OperandType::kIdx)   \
60   V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx,          \
61     OperandType::kIdx)                                                         \
62   V(StaGlobal, AccumulatorUse::kRead, OperandType::kIdx, OperandType::kIdx)    \
63                                                                                \
64   /* Context operations */                                                     \
65   V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut)                  \
66   V(PopContext, AccumulatorUse::kNone, OperandType::kReg)                      \
67   V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg,                 \
68     OperandType::kIdx, OperandType::kUImm)                                     \
69   V(LdaImmutableContextSlot, AccumulatorUse::kWrite, OperandType::kReg,        \
70     OperandType::kIdx, OperandType::kUImm)                                     \
71   V(LdaCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx)          \
72   V(LdaImmutableCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx) \
73   V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg,                  \
74     OperandType::kIdx, OperandType::kUImm)                                     \
75   V(StaCurrentContextSlot, AccumulatorUse::kRead, OperandType::kIdx)           \
76                                                                                \
77   /* Load-Store lookup slots */                                                \
78   V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx)                  \
79   V(LdaLookupContextSlot, AccumulatorUse::kWrite, OperandType::kIdx,           \
80     OperandType::kIdx, OperandType::kUImm)                                     \
81   V(LdaLookupGlobalSlot, AccumulatorUse::kWrite, OperandType::kIdx,            \
82     OperandType::kIdx, OperandType::kUImm)                                     \
83   V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx)      \
84   V(LdaLookupContextSlotInsideTypeof, AccumulatorUse::kWrite,                  \
85     OperandType::kIdx, OperandType::kIdx, OperandType::kUImm)                  \
86   V(LdaLookupGlobalSlotInsideTypeof, AccumulatorUse::kWrite,                   \
87     OperandType::kIdx, OperandType::kIdx, OperandType::kUImm)                  \
88   V(StaLookupSlot, AccumulatorUse::kReadWrite, OperandType::kIdx,              \
89     OperandType::kFlag8)                                                       \
90                                                                                \
91   /* Register-accumulator transfers */                                         \
92   V(Ldar, AccumulatorUse::kWrite, OperandType::kReg)                           \
93   V(Star, AccumulatorUse::kRead, OperandType::kRegOut)                         \
94                                                                                \
95   /* Register-register transfers */                                            \
96   V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut)       \
97                                                                                \
98   /* Property loads (LoadIC) operations */                                     \
99   V(LdaNamedProperty, AccumulatorUse::kWrite, OperandType::kReg,               \
100     OperandType::kIdx, OperandType::kIdx)                                      \
101   V(LdaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg,           \
102     OperandType::kIdx)                                                         \
103                                                                                \
104   /* Operations on module variables */                                         \
105   V(LdaModuleVariable, AccumulatorUse::kWrite, OperandType::kImm,              \
106     OperandType::kUImm)                                                        \
107   V(StaModuleVariable, AccumulatorUse::kRead, OperandType::kImm,               \
108     OperandType::kUImm)                                                        \
109                                                                                \
110   /* Propery stores (StoreIC) operations */                                    \
111   V(StaNamedProperty, AccumulatorUse::kReadWrite, OperandType::kReg,           \
112     OperandType::kIdx, OperandType::kIdx)                                      \
113   V(StaNamedOwnProperty, AccumulatorUse::kReadWrite, OperandType::kReg,        \
114     OperandType::kIdx, OperandType::kIdx)                                      \
115   V(StaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg,           \
116     OperandType::kReg, OperandType::kIdx)                                      \
117   V(StaInArrayLiteral, AccumulatorUse::kReadWrite, OperandType::kReg,          \
118     OperandType::kReg, OperandType::kIdx)                                      \
119   V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg,        \
120     OperandType::kReg, OperandType::kFlag8, OperandType::kIdx)                 \
121   V(CollectTypeProfile, AccumulatorUse::kRead, OperandType::kImm)              \
122                                                                                \
123   /* Binary Operators */                                                       \
124   V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
125   V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
126   V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
127   V(Div, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
128   V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
129   V(Exp, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
130   V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
131     OperandType::kIdx)                                                         \
132   V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
133     OperandType::kIdx)                                                         \
134   V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
135     OperandType::kIdx)                                                         \
136   V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
137     OperandType::kIdx)                                                         \
138   V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
139     OperandType::kIdx)                                                         \
140   V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg,          \
141     OperandType::kIdx)                                                         \
142                                                                                \
143   /* Binary operators with immediate operands */                               \
144   V(AddSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
145   V(SubSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
146   V(MulSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
147   V(DivSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
148   V(ModSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
149   V(ExpSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
150   V(BitwiseOrSmi, AccumulatorUse::kReadWrite, OperandType::kImm,               \
151     OperandType::kIdx)                                                         \
152   V(BitwiseXorSmi, AccumulatorUse::kReadWrite, OperandType::kImm,              \
153     OperandType::kIdx)                                                         \
154   V(BitwiseAndSmi, AccumulatorUse::kReadWrite, OperandType::kImm,              \
155     OperandType::kIdx)                                                         \
156   V(ShiftLeftSmi, AccumulatorUse::kReadWrite, OperandType::kImm,               \
157     OperandType::kIdx)                                                         \
158   V(ShiftRightSmi, AccumulatorUse::kReadWrite, OperandType::kImm,              \
159     OperandType::kIdx)                                                         \
160   V(ShiftRightLogicalSmi, AccumulatorUse::kReadWrite, OperandType::kImm,       \
161     OperandType::kIdx)                                                         \
162                                                                                \
163   /* Unary Operators */                                                        \
164   V(Inc, AccumulatorUse::kReadWrite, OperandType::kIdx)                        \
165   V(Dec, AccumulatorUse::kReadWrite, OperandType::kIdx)                        \
166   V(Negate, AccumulatorUse::kReadWrite, OperandType::kIdx)                     \
167   V(BitwiseNot, AccumulatorUse::kReadWrite, OperandType::kIdx)                 \
168   V(ToBooleanLogicalNot, AccumulatorUse::kReadWrite)                           \
169   V(LogicalNot, AccumulatorUse::kReadWrite)                                    \
170   V(TypeOf, AccumulatorUse::kReadWrite)                                        \
171   V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg)       \
172   V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg)       \
173                                                                                \
174   /* GetSuperConstructor operator */                                           \
175   V(GetSuperConstructor, AccumulatorUse::kRead, OperandType::kRegOut)          \
176                                                                                \
177   /* Call operations */                                                        \
178   V(CallAnyReceiver, AccumulatorUse::kWrite, OperandType::kReg,                \
179     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
180   V(CallProperty, AccumulatorUse::kWrite, OperandType::kReg,                   \
181     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
182   V(CallProperty0, AccumulatorUse::kWrite, OperandType::kReg,                  \
183     OperandType::kReg, OperandType::kIdx)                                      \
184   V(CallProperty1, AccumulatorUse::kWrite, OperandType::kReg,                  \
185     OperandType::kReg, OperandType::kReg, OperandType::kIdx)                   \
186   V(CallProperty2, AccumulatorUse::kWrite, OperandType::kReg,                  \
187     OperandType::kReg, OperandType::kReg, OperandType::kReg,                   \
188     OperandType::kIdx)                                                         \
189   V(CallUndefinedReceiver, AccumulatorUse::kWrite, OperandType::kReg,          \
190     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
191   V(CallUndefinedReceiver0, AccumulatorUse::kWrite, OperandType::kReg,         \
192     OperandType::kIdx)                                                         \
193   V(CallUndefinedReceiver1, AccumulatorUse::kWrite, OperandType::kReg,         \
194     OperandType::kReg, OperandType::kIdx)                                      \
195   V(CallUndefinedReceiver2, AccumulatorUse::kWrite, OperandType::kReg,         \
196     OperandType::kReg, OperandType::kReg, OperandType::kIdx)                   \
197   V(CallWithSpread, AccumulatorUse::kWrite, OperandType::kReg,                 \
198     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
199   V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId,              \
200     OperandType::kRegList, OperandType::kRegCount)                             \
201   V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId,        \
202     OperandType::kRegList, OperandType::kRegCount, OperandType::kRegOutPair)   \
203   V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kNativeContextIndex,   \
204     OperandType::kRegList, OperandType::kRegCount)                             \
205                                                                                \
206   /* Intrinsics */                                                             \
207   V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kIntrinsicId,        \
208     OperandType::kRegList, OperandType::kRegCount)                             \
209                                                                                \
210   /* Construct operators */                                                    \
211   V(Construct, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
212     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
213   V(ConstructWithSpread, AccumulatorUse::kReadWrite, OperandType::kReg,        \
214     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
215                                                                                \
216   /* Test Operators */                                                         \
217   V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
218     OperandType::kIdx)                                                         \
219   V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg,            \
220     OperandType::kIdx)                                                         \
221   V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg,               \
222     OperandType::kIdx)                                                         \
223   V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg,            \
224     OperandType::kIdx)                                                         \
225   V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg,        \
226     OperandType::kIdx)                                                         \
227   V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg,     \
228     OperandType::kIdx)                                                         \
229   V(TestReferenceEqual, AccumulatorUse::kReadWrite, OperandType::kReg)         \
230   V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg,             \
231     OperandType::kIdx)                                                         \
232   V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg)                     \
233   V(TestUndetectable, AccumulatorUse::kReadWrite)                              \
234   V(TestNull, AccumulatorUse::kReadWrite)                                      \
235   V(TestUndefined, AccumulatorUse::kReadWrite)                                 \
236   V(TestTypeOf, AccumulatorUse::kReadWrite, OperandType::kFlag8)               \
237                                                                                \
238   /* Cast operators */                                                         \
239   V(ToName, AccumulatorUse::kRead, OperandType::kRegOut)                       \
240   V(ToNumber, AccumulatorUse::kReadWrite, OperandType::kIdx)                   \
241   V(ToNumeric, AccumulatorUse::kReadWrite, OperandType::kIdx)                  \
242   V(ToObject, AccumulatorUse::kRead, OperandType::kRegOut)                     \
243   V(ToString, AccumulatorUse::kReadWrite)                                      \
244                                                                                \
245   /* Literals */                                                               \
246   V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx,            \
247     OperandType::kIdx, OperandType::kFlag8)                                    \
248   V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx,             \
249     OperandType::kIdx, OperandType::kFlag8)                                    \
250   V(CreateEmptyArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx)        \
251   V(CreateObjectLiteral, AccumulatorUse::kNone, OperandType::kIdx,             \
252     OperandType::kIdx, OperandType::kFlag8, OperandType::kRegOut)              \
253   V(CreateEmptyObjectLiteral, AccumulatorUse::kWrite)                          \
254   V(CloneObject, AccumulatorUse::kWrite, OperandType::kReg,                    \
255     OperandType::kFlag8, OperandType::kIdx)                                    \
256                                                                                \
257   /* Tagged templates */                                                       \
258   V(GetTemplateObject, AccumulatorUse::kWrite, OperandType::kIdx,              \
259     OperandType::kIdx)                                                         \
260                                                                                \
261   /* Closure allocation */                                                     \
262   V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx,                  \
263     OperandType::kIdx, OperandType::kFlag8)                                    \
264                                                                                \
265   /* Context allocation */                                                     \
266   V(CreateBlockContext, AccumulatorUse::kWrite, OperandType::kIdx)             \
267   V(CreateCatchContext, AccumulatorUse::kWrite, OperandType::kReg,             \
268     OperandType::kIdx)                                                         \
269   V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kIdx,          \
270     OperandType::kUImm)                                                        \
271   V(CreateEvalContext, AccumulatorUse::kWrite, OperandType::kIdx,              \
272     OperandType::kUImm)                                                        \
273   V(CreateWithContext, AccumulatorUse::kWrite, OperandType::kReg,              \
274     OperandType::kIdx)                                                         \
275                                                                                \
276   /* Arguments allocation */                                                   \
277   V(CreateMappedArguments, AccumulatorUse::kWrite)                             \
278   V(CreateUnmappedArguments, AccumulatorUse::kWrite)                           \
279   V(CreateRestParameter, AccumulatorUse::kWrite)                               \
280                                                                                \
281   /* Control Flow -- carefully ordered for efficient checks */                 \
282   /* - [Unconditional jumps] */                                                \
283   V(JumpLoop, AccumulatorUse::kNone, OperandType::kUImm, OperandType::kImm)    \
284   /* - [Forward jumps] */                                                      \
285   V(Jump, AccumulatorUse::kNone, OperandType::kUImm)                           \
286   /* - [Start constant jumps] */                                               \
287   V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx)                    \
288   /* - [Conditional jumps] */                                                  \
289   /* - [Conditional constant jumps] */                                         \
290   V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
291   V(JumpIfNotNullConstant, AccumulatorUse::kRead, OperandType::kIdx)           \
292   V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx)         \
293   V(JumpIfNotUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx)      \
294   V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
295   V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)             \
296   V(JumpIfJSReceiverConstant, AccumulatorUse::kRead, OperandType::kIdx)        \
297   /* - [Start ToBoolean jumps] */                                              \
298   V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)     \
299   V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)    \
300   /* - [End constant jumps] */                                                 \
301   /* - [Conditional immediate jumps] */                                        \
302   V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kUImm)            \
303   V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kUImm)           \
304   /* - [End ToBoolean jumps] */                                                \
305   V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kUImm)                     \
306   V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kUImm)                    \
307   V(JumpIfNull, AccumulatorUse::kRead, OperandType::kUImm)                     \
308   V(JumpIfNotNull, AccumulatorUse::kRead, OperandType::kUImm)                  \
309   V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kUImm)                \
310   V(JumpIfNotUndefined, AccumulatorUse::kRead, OperandType::kUImm)             \
311   V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kUImm)               \
312                                                                                \
313   /* Smi-table lookup for switch statements */                                 \
314   V(SwitchOnSmiNoFeedback, AccumulatorUse::kRead, OperandType::kIdx,           \
315     OperandType::kUImm, OperandType::kImm)                                     \
316                                                                                \
317   /* Complex flow control For..in */                                           \
318   V(ForInEnumerate, AccumulatorUse::kWrite, OperandType::kReg)                 \
319   V(ForInPrepare, AccumulatorUse::kRead, OperandType::kRegOutTriple,           \
320     OperandType::kIdx)                                                         \
321   V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg,                  \
322     OperandType::kReg)                                                         \
323   V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg,   \
324     OperandType::kRegPair, OperandType::kIdx)                                  \
325   V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg)                      \
326                                                                                \
327   /* Perform a stack guard check */                                            \
328   V(StackCheck, AccumulatorUse::kNone)                                         \
329                                                                                \
330   /* Update the pending message */                                             \
331   V(SetPendingMessage, AccumulatorUse::kReadWrite)                             \
332                                                                                \
333   /* Non-local flow control */                                                 \
334   V(Throw, AccumulatorUse::kRead)                                              \
335   V(ReThrow, AccumulatorUse::kRead)                                            \
336   V(Return, AccumulatorUse::kRead)                                             \
337   V(ThrowReferenceErrorIfHole, AccumulatorUse::kRead, OperandType::kIdx)       \
338   V(ThrowSuperNotCalledIfHole, AccumulatorUse::kRead)                          \
339   V(ThrowSuperAlreadyCalledIfNotHole, AccumulatorUse::kRead)                   \
340                                                                                \
341   /* Generators */                                                             \
342   V(SwitchOnGeneratorState, AccumulatorUse::kNone, OperandType::kReg,          \
343     OperandType::kIdx, OperandType::kUImm)                                     \
344   V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg,                \
345     OperandType::kRegList, OperandType::kRegCount, OperandType::kUImm)         \
346   V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg,                \
347     OperandType::kRegOutList, OperandType::kRegCount)                          \
348                                                                                \
349   /* Debugger */                                                               \
350   V(Debugger, AccumulatorUse::kNone)                                           \
351                                                                                \
352   /* Block Coverage */                                                         \
353   V(IncBlockCounter, AccumulatorUse::kNone, OperandType::kIdx)                 \
354                                                                                \
355   /* Execution Abort (internal error) */                                       \
356   V(Abort, AccumulatorUse::kNone, OperandType::kIdx)                           \
357                                                                                \
358   /* Illegal bytecode  */                                                      \
359   V(Illegal, AccumulatorUse::kNone)
360 
361 // List of debug break bytecodes.
362 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
363   V(DebugBreak0)                           \
364   V(DebugBreak1)                           \
365   V(DebugBreak2)                           \
366   V(DebugBreak3)                           \
367   V(DebugBreak4)                           \
368   V(DebugBreak5)                           \
369   V(DebugBreak6)
370 
371 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
372   V(DebugBreakWide)                         \
373   V(DebugBreakExtraWide)
374 
375 #define DEBUG_BREAK_BYTECODE_LIST(V) \
376   DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
377   DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
378 
379 // Lists of jump bytecodes.
380 
381 #define JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
382   V(JumpLoop)                                         \
383   V(Jump)
384 
385 #define JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) V(JumpConstant)
386 
387 #define JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
388   V(JumpIfToBooleanTrue)                                      \
389   V(JumpIfToBooleanFalse)
390 
391 #define JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \
392   V(JumpIfToBooleanTrueConstant)                             \
393   V(JumpIfToBooleanFalseConstant)
394 
395 #define JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V)     \
396   JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
397   V(JumpIfTrue)                                         \
398   V(JumpIfFalse)                                        \
399   V(JumpIfNull)                                         \
400   V(JumpIfNotNull)                                      \
401   V(JumpIfUndefined)                                    \
402   V(JumpIfNotUndefined)                                 \
403   V(JumpIfJSReceiver)                                   \
404 
405 #define JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)     \
406   JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \
407   V(JumpIfNullConstant)                                \
408   V(JumpIfNotNullConstant)                             \
409   V(JumpIfUndefinedConstant)                           \
410   V(JumpIfNotUndefinedConstant)                        \
411   V(JumpIfTrueConstant)                                \
412   V(JumpIfFalseConstant)                               \
413   V(JumpIfJSReceiverConstant)                          \
414 
415 #define JUMP_CONSTANT_BYTECODE_LIST(V)         \
416   JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) \
417   JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)
418 
419 #define JUMP_IMMEDIATE_BYTECODE_LIST(V)         \
420   JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
421   JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V)
422 
423 #define JUMP_TO_BOOLEAN_BYTECODE_LIST(V)                \
424   JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
425   JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)
426 
427 #define JUMP_UNCONDITIONAL_BYTECODE_LIST(V)     \
428   JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
429   JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V)
430 
431 #define JUMP_CONDITIONAL_BYTECODE_LIST(V)     \
432   JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
433   JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)
434 
435 #define JUMP_FORWARD_BYTECODE_LIST(V) \
436   V(Jump)                             \
437   V(JumpConstant)                     \
438   JUMP_CONDITIONAL_BYTECODE_LIST(V)
439 
440 #define JUMP_BYTECODE_LIST(V)   \
441   JUMP_FORWARD_BYTECODE_LIST(V) \
442   V(JumpLoop)
443 
444 #define RETURN_BYTECODE_LIST(V) \
445   V(Return)                     \
446   V(SuspendGenerator)
447 
448 // Enumeration of interpreter bytecodes.
449 enum class Bytecode : uint8_t {
450 #define DECLARE_BYTECODE(Name, ...) k##Name,
451   BYTECODE_LIST(DECLARE_BYTECODE)
452 #undef DECLARE_BYTECODE
453 #define COUNT_BYTECODE(x, ...) +1
454   // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
455   // evaluate to the same value as the last real bytecode.
456   kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
457 #undef COUNT_BYTECODE
458 };
459 
460 class V8_EXPORT_PRIVATE Bytecodes final : public AllStatic {
461  public:
462   // The maximum number of operands a bytecode may have.
463   static const int kMaxOperands = 5;
464 
465   // The total number of bytecodes used.
466   static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1;
467 
468   // Returns string representation of |bytecode|.
469   static const char* ToString(Bytecode bytecode);
470 
471   // Returns string representation of |bytecode|.
472   static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
473 
474   // Returns byte value of bytecode.
ToByte(Bytecode bytecode)475   static uint8_t ToByte(Bytecode bytecode) {
476     DCHECK_LE(bytecode, Bytecode::kLast);
477     return static_cast<uint8_t>(bytecode);
478   }
479 
480   // Returns bytecode for |value|.
FromByte(uint8_t value)481   static Bytecode FromByte(uint8_t value) {
482     Bytecode bytecode = static_cast<Bytecode>(value);
483     DCHECK_LE(bytecode, Bytecode::kLast);
484     return bytecode;
485   }
486 
487   // Returns the prefix bytecode representing an operand scale to be
488   // applied to a a bytecode.
OperandScaleToPrefixBytecode(OperandScale operand_scale)489   static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale) {
490     switch (operand_scale) {
491       case OperandScale::kQuadruple:
492         return Bytecode::kExtraWide;
493       case OperandScale::kDouble:
494         return Bytecode::kWide;
495       default:
496         UNREACHABLE();
497     }
498   }
499 
500   // Returns true if the operand scale requires a prefix bytecode.
OperandScaleRequiresPrefixBytecode(OperandScale operand_scale)501   static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
502     return operand_scale != OperandScale::kSingle;
503   }
504 
505   // Returns the scaling applied to scalable operands if bytecode is
506   // is a scaling prefix.
PrefixBytecodeToOperandScale(Bytecode bytecode)507   static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode) {
508     switch (bytecode) {
509       case Bytecode::kExtraWide:
510       case Bytecode::kDebugBreakExtraWide:
511         return OperandScale::kQuadruple;
512       case Bytecode::kWide:
513       case Bytecode::kDebugBreakWide:
514         return OperandScale::kDouble;
515       default:
516         UNREACHABLE();
517     }
518   }
519 
520   // Returns how accumulator is used by |bytecode|.
GetAccumulatorUse(Bytecode bytecode)521   static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) {
522     DCHECK_LE(bytecode, Bytecode::kLast);
523     return kAccumulatorUse[static_cast<size_t>(bytecode)];
524   }
525 
526   // Returns true if |bytecode| reads the accumulator.
ReadsAccumulator(Bytecode bytecode)527   static bool ReadsAccumulator(Bytecode bytecode) {
528     return BytecodeOperands::ReadsAccumulator(GetAccumulatorUse(bytecode));
529   }
530 
531   // Returns true if |bytecode| writes the accumulator.
WritesAccumulator(Bytecode bytecode)532   static bool WritesAccumulator(Bytecode bytecode) {
533     return BytecodeOperands::WritesAccumulator(GetAccumulatorUse(bytecode));
534   }
535 
536   // Return true if |bytecode| is an accumulator load without effects,
537   // e.g. LdaConstant, LdaTrue, Ldar.
IsAccumulatorLoadWithoutEffects(Bytecode bytecode)538   static constexpr bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
539     return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero ||
540            bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull ||
541            bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
542            bytecode == Bytecode::kLdaUndefined ||
543            bytecode == Bytecode::kLdaTheHole ||
544            bytecode == Bytecode::kLdaConstant ||
545            bytecode == Bytecode::kLdaContextSlot ||
546            bytecode == Bytecode::kLdaCurrentContextSlot ||
547            bytecode == Bytecode::kLdaImmutableContextSlot ||
548            bytecode == Bytecode::kLdaImmutableCurrentContextSlot;
549   }
550 
551   // Returns true if |bytecode| is a compare operation without external effects
552   // (e.g., Type cooersion).
IsCompareWithoutEffects(Bytecode bytecode)553   static constexpr bool IsCompareWithoutEffects(Bytecode bytecode) {
554     return bytecode == Bytecode::kTestUndetectable ||
555            bytecode == Bytecode::kTestNull ||
556            bytecode == Bytecode::kTestUndefined ||
557            bytecode == Bytecode::kTestTypeOf;
558   }
559 
560   // Return true if |bytecode| is a register load without effects,
561   // e.g. Mov, Star.
IsRegisterLoadWithoutEffects(Bytecode bytecode)562   static constexpr bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
563     return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
564            bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
565   }
566 
567   // Returns true if the bytecode is a conditional jump taking
568   // an immediate byte operand (OperandType::kImm).
IsConditionalJumpImmediate(Bytecode bytecode)569   static constexpr bool IsConditionalJumpImmediate(Bytecode bytecode) {
570     return bytecode >= Bytecode::kJumpIfToBooleanTrue &&
571            bytecode <= Bytecode::kJumpIfJSReceiver;
572   }
573 
574   // Returns true if the bytecode is a conditional jump taking
575   // a constant pool entry (OperandType::kIdx).
IsConditionalJumpConstant(Bytecode bytecode)576   static constexpr bool IsConditionalJumpConstant(Bytecode bytecode) {
577     return bytecode >= Bytecode::kJumpIfNullConstant &&
578            bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
579   }
580 
581   // Returns true if the bytecode is a conditional jump taking
582   // any kind of operand.
IsConditionalJump(Bytecode bytecode)583   static constexpr bool IsConditionalJump(Bytecode bytecode) {
584     return bytecode >= Bytecode::kJumpIfNullConstant &&
585            bytecode <= Bytecode::kJumpIfJSReceiver;
586   }
587 
588   // Returns true if the bytecode is an unconditional jump.
IsUnconditionalJump(Bytecode bytecode)589   static constexpr bool IsUnconditionalJump(Bytecode bytecode) {
590     return bytecode >= Bytecode::kJumpLoop &&
591            bytecode <= Bytecode::kJumpConstant;
592   }
593 
594   // Returns true if the bytecode is a jump or a conditional jump taking
595   // an immediate byte operand (OperandType::kImm).
IsJumpImmediate(Bytecode bytecode)596   static constexpr bool IsJumpImmediate(Bytecode bytecode) {
597     return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
598            IsConditionalJumpImmediate(bytecode);
599   }
600 
601   // Returns true if the bytecode is a jump or conditional jump taking a
602   // constant pool entry (OperandType::kIdx).
IsJumpConstant(Bytecode bytecode)603   static constexpr bool IsJumpConstant(Bytecode bytecode) {
604     return bytecode >= Bytecode::kJumpConstant &&
605            bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
606   }
607 
608   // Returns true if the bytecode is a jump that internally coerces the
609   // accumulator to a boolean.
IsJumpIfToBoolean(Bytecode bytecode)610   static constexpr bool IsJumpIfToBoolean(Bytecode bytecode) {
611     return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant &&
612            bytecode <= Bytecode::kJumpIfToBooleanFalse;
613   }
614 
615   // Returns true if the bytecode is a jump or conditional jump taking
616   // any kind of operand.
IsJump(Bytecode bytecode)617   static constexpr bool IsJump(Bytecode bytecode) {
618     return bytecode >= Bytecode::kJumpLoop &&
619            bytecode <= Bytecode::kJumpIfJSReceiver;
620   }
621 
622   // Returns true if the bytecode is a forward jump or conditional jump taking
623   // any kind of operand.
IsForwardJump(Bytecode bytecode)624   static constexpr bool IsForwardJump(Bytecode bytecode) {
625     return bytecode >= Bytecode::kJump &&
626            bytecode <= Bytecode::kJumpIfJSReceiver;
627   }
628 
629   // Return true if |bytecode| is a jump without effects,
630   // e.g.  any jump excluding those that include type coercion like
631   // JumpIfTrueToBoolean.
IsJumpWithoutEffects(Bytecode bytecode)632   static constexpr bool IsJumpWithoutEffects(Bytecode bytecode) {
633     return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
634   }
635 
636   // Returns true if the bytecode is a switch.
IsSwitch(Bytecode bytecode)637   static constexpr bool IsSwitch(Bytecode bytecode) {
638     return bytecode == Bytecode::kSwitchOnSmiNoFeedback ||
639            bytecode == Bytecode::kSwitchOnGeneratorState;
640   }
641 
642   // Returns true if |bytecode| has no effects. These bytecodes only manipulate
643   // interpreter frame state and will never throw.
IsWithoutExternalSideEffects(Bytecode bytecode)644   static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) {
645     return (IsAccumulatorLoadWithoutEffects(bytecode) ||
646             IsRegisterLoadWithoutEffects(bytecode) ||
647             IsCompareWithoutEffects(bytecode) ||
648             IsJumpWithoutEffects(bytecode) || IsSwitch(bytecode));
649   }
650 
651   // Returns true if the bytecode is Ldar or Star.
IsLdarOrStar(Bytecode bytecode)652   static constexpr bool IsLdarOrStar(Bytecode bytecode) {
653     return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
654   }
655 
656   // Returns true if the bytecode is a call or a constructor call.
IsCallOrConstruct(Bytecode bytecode)657   static constexpr bool IsCallOrConstruct(Bytecode bytecode) {
658     return bytecode == Bytecode::kCallAnyReceiver ||
659            bytecode == Bytecode::kCallProperty ||
660            bytecode == Bytecode::kCallProperty0 ||
661            bytecode == Bytecode::kCallProperty1 ||
662            bytecode == Bytecode::kCallProperty2 ||
663            bytecode == Bytecode::kCallUndefinedReceiver ||
664            bytecode == Bytecode::kCallUndefinedReceiver0 ||
665            bytecode == Bytecode::kCallUndefinedReceiver1 ||
666            bytecode == Bytecode::kCallUndefinedReceiver2 ||
667            bytecode == Bytecode::kConstruct ||
668            bytecode == Bytecode::kCallWithSpread ||
669            bytecode == Bytecode::kConstructWithSpread ||
670            bytecode == Bytecode::kCallJSRuntime;
671   }
672 
673   // Returns true if the bytecode is a call to the runtime.
IsCallRuntime(Bytecode bytecode)674   static constexpr bool IsCallRuntime(Bytecode bytecode) {
675     return bytecode == Bytecode::kCallRuntime ||
676            bytecode == Bytecode::kCallRuntimeForPair ||
677            bytecode == Bytecode::kInvokeIntrinsic;
678   }
679 
680   // Returns true if the bytecode is a scaling prefix bytecode.
IsPrefixScalingBytecode(Bytecode bytecode)681   static constexpr bool IsPrefixScalingBytecode(Bytecode bytecode) {
682     return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide ||
683            bytecode == Bytecode::kDebugBreakExtraWide ||
684            bytecode == Bytecode::kDebugBreakWide;
685   }
686 
687   // Returns true if the bytecode can be lazily deserialized.
IsLazy(Bytecode bytecode)688   static constexpr bool IsLazy(Bytecode bytecode) {
689     // Currently, all handlers are deserialized lazily.
690     return true;
691   }
692 
693   // Returns true if the bytecode returns.
Returns(Bytecode bytecode)694   static constexpr bool Returns(Bytecode bytecode) {
695 #define OR_BYTECODE(NAME) || bytecode == Bytecode::k##NAME
696     return false RETURN_BYTECODE_LIST(OR_BYTECODE);
697 #undef OR_BYTECODE
698   }
699 
700   // Returns the number of operands expected by |bytecode|.
NumberOfOperands(Bytecode bytecode)701   static int NumberOfOperands(Bytecode bytecode) {
702     DCHECK_LE(bytecode, Bytecode::kLast);
703     return kOperandCount[static_cast<size_t>(bytecode)];
704   }
705 
706   // Returns the i-th operand of |bytecode|.
GetOperandType(Bytecode bytecode,int i)707   static OperandType GetOperandType(Bytecode bytecode, int i) {
708     DCHECK_LE(bytecode, Bytecode::kLast);
709     DCHECK_LT(i, NumberOfOperands(bytecode));
710     DCHECK_GE(i, 0);
711     return GetOperandTypes(bytecode)[i];
712   }
713 
714   // Returns a pointer to an array of operand types terminated in
715   // OperandType::kNone.
GetOperandTypes(Bytecode bytecode)716   static const OperandType* GetOperandTypes(Bytecode bytecode) {
717     DCHECK_LE(bytecode, Bytecode::kLast);
718     return kOperandTypes[static_cast<size_t>(bytecode)];
719   }
720 
OperandIsScalableSignedByte(Bytecode bytecode,int operand_index)721   static bool OperandIsScalableSignedByte(Bytecode bytecode,
722                                           int operand_index) {
723     DCHECK_LE(bytecode, Bytecode::kLast);
724     return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
725            OperandTypeInfo::kScalableSignedByte;
726   }
727 
OperandIsScalableUnsignedByte(Bytecode bytecode,int operand_index)728   static bool OperandIsScalableUnsignedByte(Bytecode bytecode,
729                                             int operand_index) {
730     DCHECK_LE(bytecode, Bytecode::kLast);
731     return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
732            OperandTypeInfo::kScalableUnsignedByte;
733   }
734 
OperandIsScalable(Bytecode bytecode,int operand_index)735   static bool OperandIsScalable(Bytecode bytecode, int operand_index) {
736     return OperandIsScalableSignedByte(bytecode, operand_index) ||
737            OperandIsScalableUnsignedByte(bytecode, operand_index);
738   }
739 
740   // Returns true if the bytecode has wider operand forms.
741   static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
742 
743   // Returns the size of the i-th operand of |bytecode|.
GetOperandSize(Bytecode bytecode,int i,OperandScale operand_scale)744   static OperandSize GetOperandSize(Bytecode bytecode, int i,
745                                     OperandScale operand_scale) {
746     CHECK_LT(i, NumberOfOperands(bytecode));
747     return GetOperandSizes(bytecode, operand_scale)[i];
748   }
749 
750   // Returns the operand sizes of |bytecode| with scale |operand_scale|.
GetOperandSizes(Bytecode bytecode,OperandScale operand_scale)751   static const OperandSize* GetOperandSizes(Bytecode bytecode,
752                                             OperandScale operand_scale) {
753     DCHECK_LE(bytecode, Bytecode::kLast);
754     DCHECK_GE(operand_scale, OperandScale::kSingle);
755     DCHECK_LE(operand_scale, OperandScale::kLast);
756     STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
757                   OperandScale::kLast == OperandScale::kQuadruple);
758     int scale_index = static_cast<int>(operand_scale) >> 1;
759     return kOperandSizes[scale_index][static_cast<size_t>(bytecode)];
760   }
761 
762   // Returns the offset of the i-th operand of |bytecode| relative to the start
763   // of the bytecode.
764   static int GetOperandOffset(Bytecode bytecode, int i,
765                               OperandScale operand_scale);
766 
767   // Returns the size of the bytecode including its operands for the
768   // given |operand_scale|.
Size(Bytecode bytecode,OperandScale operand_scale)769   static int Size(Bytecode bytecode, OperandScale operand_scale) {
770     DCHECK_LE(bytecode, Bytecode::kLast);
771     STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
772                   OperandScale::kLast == OperandScale::kQuadruple);
773     int scale_index = static_cast<int>(operand_scale) >> 1;
774     return kBytecodeSizes[scale_index][static_cast<size_t>(bytecode)];
775   }
776 
777   // Returns a debug break bytecode to replace |bytecode|.
778   static Bytecode GetDebugBreak(Bytecode bytecode);
779 
780   // Returns the equivalent jump bytecode without the accumulator coercion.
781   static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
782 
783   // Returns true if there is a call in the most-frequently executed path
784   // through the bytecode's handler.
785   static bool MakesCallAlongCriticalPath(Bytecode bytecode);
786 
787   // Returns the receiver mode of the given call bytecode.
GetReceiverMode(Bytecode bytecode)788   static ConvertReceiverMode GetReceiverMode(Bytecode bytecode) {
789     DCHECK(IsCallOrConstruct(bytecode) ||
790            bytecode == Bytecode::kInvokeIntrinsic);
791     switch (bytecode) {
792       case Bytecode::kCallProperty:
793       case Bytecode::kCallProperty0:
794       case Bytecode::kCallProperty1:
795       case Bytecode::kCallProperty2:
796         return ConvertReceiverMode::kNotNullOrUndefined;
797       case Bytecode::kCallUndefinedReceiver:
798       case Bytecode::kCallUndefinedReceiver0:
799       case Bytecode::kCallUndefinedReceiver1:
800       case Bytecode::kCallUndefinedReceiver2:
801       case Bytecode::kCallJSRuntime:
802         return ConvertReceiverMode::kNullOrUndefined;
803       case Bytecode::kCallAnyReceiver:
804       case Bytecode::kConstruct:
805       case Bytecode::kCallWithSpread:
806       case Bytecode::kConstructWithSpread:
807       case Bytecode::kInvokeIntrinsic:
808         return ConvertReceiverMode::kAny;
809       default:
810         UNREACHABLE();
811     }
812   }
813 
814   // Returns true if the bytecode is a debug break.
815   static bool IsDebugBreak(Bytecode bytecode);
816 
817   // Returns true if |operand_type| is any type of register operand.
818   static bool IsRegisterOperandType(OperandType operand_type);
819 
820   // Returns true if |operand_type| represents a register used as an input.
821   static bool IsRegisterInputOperandType(OperandType operand_type);
822 
823   // Returns true if |operand_type| represents a register used as an output.
824   static bool IsRegisterOutputOperandType(OperandType operand_type);
825 
826   // Returns true if |operand_type| represents a register list operand.
827   static bool IsRegisterListOperandType(OperandType operand_type);
828 
829   // Returns true if the handler for |bytecode| should look ahead and inline a
830   // dispatch to a Star bytecode.
831   static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale);
832 
833   // Returns the number of registers represented by a register operand. For
834   // instance, a RegPair represents two registers. Should not be called for
835   // kRegList which has a variable number of registers based on the following
836   // kRegCount operand.
GetNumberOfRegistersRepresentedBy(OperandType operand_type)837   static int GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
838     switch (operand_type) {
839       case OperandType::kReg:
840       case OperandType::kRegOut:
841         return 1;
842       case OperandType::kRegPair:
843       case OperandType::kRegOutPair:
844         return 2;
845       case OperandType::kRegOutTriple:
846         return 3;
847       case OperandType::kRegList:
848       case OperandType::kRegOutList:
849         UNREACHABLE();
850       default:
851         return 0;
852     }
853     UNREACHABLE();
854   }
855 
856   // Returns the size of |operand_type| for |operand_scale|.
SizeOfOperand(OperandType operand_type,OperandScale operand_scale)857   static OperandSize SizeOfOperand(OperandType operand_type,
858                                    OperandScale operand_scale) {
859     DCHECK_LE(operand_type, OperandType::kLast);
860     DCHECK_GE(operand_scale, OperandScale::kSingle);
861     DCHECK_LE(operand_scale, OperandScale::kLast);
862     STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
863                   OperandScale::kLast == OperandScale::kQuadruple);
864     int scale_index = static_cast<int>(operand_scale) >> 1;
865     return kOperandKindSizes[scale_index][static_cast<size_t>(operand_type)];
866   }
867 
868   // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
869   static bool IsRuntimeIdOperandType(OperandType operand_type);
870 
871   // Returns true if |operand_type| is unsigned, false if signed.
872   static bool IsUnsignedOperandType(OperandType operand_type);
873 
874   // Returns true if a handler is generated for a bytecode at a given
875   // operand scale. All bytecodes have handlers at OperandScale::kSingle,
876   // but only bytecodes with scalable operands have handlers with larger
877   // OperandScale values.
878   static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
879 
880   // Return the operand scale required to hold a signed operand with |value|.
ScaleForSignedOperand(int32_t value)881   static OperandScale ScaleForSignedOperand(int32_t value) {
882     if (value >= kMinInt8 && value <= kMaxInt8) {
883       return OperandScale::kSingle;
884     } else if (value >= kMinInt16 && value <= kMaxInt16) {
885       return OperandScale::kDouble;
886     } else {
887       return OperandScale::kQuadruple;
888     }
889   }
890 
891   // Return the operand scale required to hold an unsigned operand with |value|.
ScaleForUnsignedOperand(uint32_t value)892   static OperandScale ScaleForUnsignedOperand(uint32_t value) {
893     if (value <= kMaxUInt8) {
894       return OperandScale::kSingle;
895     } else if (value <= kMaxUInt16) {
896       return OperandScale::kDouble;
897     } else {
898       return OperandScale::kQuadruple;
899     }
900   }
901 
902   // Return the operand size required to hold an unsigned operand with |value|.
SizeForUnsignedOperand(uint32_t value)903   static OperandSize SizeForUnsignedOperand(uint32_t value) {
904     if (value <= kMaxUInt8) {
905       return OperandSize::kByte;
906     } else if (value <= kMaxUInt16) {
907       return OperandSize::kShort;
908     } else {
909       return OperandSize::kQuad;
910     }
911   }
912 
bytecode_size_table_address()913   static Address bytecode_size_table_address() {
914     return reinterpret_cast<Address>(const_cast<int*>(&kBytecodeSizes[0][0]));
915   }
916 
917  private:
918   static const OperandType* const kOperandTypes[];
919   static const OperandTypeInfo* const kOperandTypeInfos[];
920   static const int kOperandCount[];
921   static const int kNumberOfRegisterOperands[];
922   static const AccumulatorUse kAccumulatorUse[];
923   static const bool kIsScalable[];
924   static const int kBytecodeSizes[3][kBytecodeCount];
925   static const OperandSize* const kOperandSizes[3][kBytecodeCount];
926   static OperandSize const
927       kOperandKindSizes[3][BytecodeOperands::kOperandTypeCount];
928 };
929 
930 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
931                                            const Bytecode& bytecode);
932 
933 }  // namespace interpreter
934 }  // namespace internal
935 }  // namespace v8
936 
937 #endif  // V8_INTERPRETER_BYTECODES_H_
938