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