• 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 <iosfwd>
9 
10 // Clients of this interface shouldn't depend on lots of interpreter internals.
11 // Do not include anything from src/interpreter here!
12 #include "src/frames.h"
13 #include "src/utils.h"
14 
15 namespace v8 {
16 namespace internal {
17 namespace interpreter {
18 
19 #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone)
20 
21 #define REGISTER_INPUT_OPERAND_TYPE_LIST(V)         \
22   V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \
23   V(Reg, OperandTypeInfo::kScalableSignedByte)      \
24   V(RegPair, OperandTypeInfo::kScalableSignedByte)
25 
26 #define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)          \
27   V(RegOut, OperandTypeInfo::kScalableSignedByte)     \
28   V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
29   V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
30 
31 #define SCALAR_OPERAND_TYPE_LIST(V)                   \
32   V(Flag8, OperandTypeInfo::kFixedUnsignedByte)       \
33   V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \
34   V(Idx, OperandTypeInfo::kScalableUnsignedByte)      \
35   V(Imm, OperandTypeInfo::kScalableSignedByte)        \
36   V(RegCount, OperandTypeInfo::kScalableUnsignedByte) \
37   V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)
38 
39 #define REGISTER_OPERAND_TYPE_LIST(V) \
40   REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
41   REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
42 
43 #define NON_REGISTER_OPERAND_TYPE_LIST(V) \
44   INVALID_OPERAND_TYPE_LIST(V)            \
45   SCALAR_OPERAND_TYPE_LIST(V)
46 
47 // The list of operand types used by bytecodes.
48 #define OPERAND_TYPE_LIST(V)        \
49   NON_REGISTER_OPERAND_TYPE_LIST(V) \
50   REGISTER_OPERAND_TYPE_LIST(V)
51 
52 // Define one debug break bytecode for each possible size of unscaled
53 // bytecodes. Format is V(<bytecode>, <accumulator_use>, <operands>).
54 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V)                                    \
55   V(DebugBreak0, AccumulatorUse::kRead)                                       \
56   V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg)                    \
57   V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \
58   V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
59     OperandType::kReg)                                                        \
60   V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
61     OperandType::kReg, OperandType::kReg)                                     \
62   V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId,              \
63     OperandType::kReg, OperandType::kReg)                                     \
64   V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId,              \
65     OperandType::kReg, OperandType::kReg, OperandType::kReg)
66 
67 // Define one debug break for each widening prefix.
68 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
69   V(DebugBreakWide, AccumulatorUse::kRead)  \
70   V(DebugBreakExtraWide, AccumulatorUse::kRead)
71 
72 #define DEBUG_BREAK_BYTECODE_LIST(V) \
73   DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
74   DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
75 
76 // The list of bytecodes which are interpreted by the interpreter.
77 #define BYTECODE_LIST(V)                                                       \
78   /* Extended width operands */                                                \
79   V(Wide, AccumulatorUse::kNone)                                               \
80   V(ExtraWide, AccumulatorUse::kNone)                                          \
81                                                                                \
82   /* Loading the accumulator */                                                \
83   V(LdaZero, AccumulatorUse::kWrite)                                           \
84   V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm)                         \
85   V(LdaUndefined, AccumulatorUse::kWrite)                                      \
86   V(LdaNull, AccumulatorUse::kWrite)                                           \
87   V(LdaTheHole, AccumulatorUse::kWrite)                                        \
88   V(LdaTrue, AccumulatorUse::kWrite)                                           \
89   V(LdaFalse, AccumulatorUse::kWrite)                                          \
90   V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx)                    \
91                                                                                \
92   /* Loading registers */                                                      \
93   V(LdrUndefined, AccumulatorUse::kNone, OperandType::kRegOut)                 \
94                                                                                \
95   /* Globals */                                                                \
96   V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx)                      \
97   V(LdrGlobal, AccumulatorUse::kNone, OperandType::kIdx, OperandType::kRegOut) \
98   V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx)          \
99   V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx,                 \
100     OperandType::kIdx)                                                         \
101   V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx,                 \
102     OperandType::kIdx)                                                         \
103                                                                                \
104   /* Context operations */                                                     \
105   V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut)                  \
106   V(PopContext, AccumulatorUse::kNone, OperandType::kReg)                      \
107   V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg,                 \
108     OperandType::kIdx)                                                         \
109   V(LdrContextSlot, AccumulatorUse::kNone, OperandType::kReg,                  \
110     OperandType::kIdx, OperandType::kRegOut)                                   \
111   V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg,                  \
112     OperandType::kIdx)                                                         \
113                                                                                \
114   /* Load-Store lookup slots */                                                \
115   V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx)                  \
116   V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx)      \
117   V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx)        \
118   V(StaLookupSlotStrict, AccumulatorUse::kReadWrite, OperandType::kIdx)        \
119                                                                                \
120   /* Register-accumulator transfers */                                         \
121   V(Ldar, AccumulatorUse::kWrite, OperandType::kReg)                           \
122   V(Star, AccumulatorUse::kRead, OperandType::kRegOut)                         \
123                                                                                \
124   /* Register-register transfers */                                            \
125   V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut)       \
126                                                                                \
127   /* Property loads (LoadIC) operations */                                     \
128   V(LdaNamedProperty, AccumulatorUse::kWrite, OperandType::kReg,               \
129     OperandType::kIdx, OperandType::kIdx)                                      \
130   V(LdrNamedProperty, AccumulatorUse::kNone, OperandType::kReg,                \
131     OperandType::kIdx, OperandType::kIdx, OperandType::kRegOut)                \
132   V(LdaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg,           \
133     OperandType::kIdx)                                                         \
134   V(LdrKeyedProperty, AccumulatorUse::kRead, OperandType::kReg,                \
135     OperandType::kIdx, OperandType::kRegOut)                                   \
136                                                                                \
137   /* Propery stores (StoreIC) operations */                                    \
138   V(StaNamedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg,          \
139     OperandType::kIdx, OperandType::kIdx)                                      \
140   V(StaNamedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg,          \
141     OperandType::kIdx, OperandType::kIdx)                                      \
142   V(StaKeyedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg,          \
143     OperandType::kReg, OperandType::kIdx)                                      \
144   V(StaKeyedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg,          \
145     OperandType::kReg, OperandType::kIdx)                                      \
146                                                                                \
147   /* Binary Operators */                                                       \
148   V(Add, AccumulatorUse::kReadWrite, OperandType::kReg)                        \
149   V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg)                        \
150   V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg)                        \
151   V(Div, AccumulatorUse::kReadWrite, OperandType::kReg)                        \
152   V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg)                        \
153   V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg)                  \
154   V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg)                 \
155   V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg)                 \
156   V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg)                  \
157   V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg)                 \
158   V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg)          \
159                                                                                \
160   /* Unary Operators */                                                        \
161   V(Inc, AccumulatorUse::kReadWrite)                                           \
162   V(Dec, AccumulatorUse::kReadWrite)                                           \
163   V(ToBooleanLogicalNot, AccumulatorUse::kReadWrite)                           \
164   V(LogicalNot, AccumulatorUse::kReadWrite)                                    \
165   V(TypeOf, AccumulatorUse::kReadWrite)                                        \
166   V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg)       \
167   V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg)       \
168                                                                                \
169   /* Call operations */                                                        \
170   V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg,        \
171     OperandType::kRegCount, OperandType::kIdx)                                 \
172   V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg,    \
173     OperandType::kRegCount, OperandType::kIdx)                                 \
174   V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId,              \
175     OperandType::kMaybeReg, OperandType::kRegCount)                            \
176   V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId,        \
177     OperandType::kMaybeReg, OperandType::kRegCount, OperandType::kRegOutPair)  \
178   V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kIdx,                  \
179     OperandType::kReg, OperandType::kRegCount)                                 \
180                                                                                \
181   /* Intrinsics */                                                             \
182   V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kIntrinsicId,        \
183     OperandType::kMaybeReg, OperandType::kRegCount)                            \
184                                                                                \
185   /* New operator */                                                           \
186   V(New, AccumulatorUse::kReadWrite, OperandType::kReg,                        \
187     OperandType::kMaybeReg, OperandType::kRegCount)                            \
188                                                                                \
189   /* Test Operators */                                                         \
190   V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg)                  \
191   V(TestNotEqual, AccumulatorUse::kReadWrite, OperandType::kReg)               \
192   V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg)            \
193   V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg)               \
194   V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg)            \
195   V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg)        \
196   V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg)     \
197   V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg)             \
198   V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg)                     \
199                                                                                \
200   /* Cast operators */                                                         \
201   V(ToName, AccumulatorUse::kReadWrite)                                        \
202   V(ToNumber, AccumulatorUse::kReadWrite)                                      \
203   V(ToObject, AccumulatorUse::kReadWrite)                                      \
204                                                                                \
205   /* Literals */                                                               \
206   V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx,            \
207     OperandType::kIdx, OperandType::kFlag8)                                    \
208   V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx,             \
209     OperandType::kIdx, OperandType::kFlag8)                                    \
210   V(CreateObjectLiteral, AccumulatorUse::kWrite, OperandType::kIdx,            \
211     OperandType::kIdx, OperandType::kFlag8)                                    \
212                                                                                \
213   /* Closure allocation */                                                     \
214   V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx,                  \
215     OperandType::kFlag8)                                                       \
216                                                                                \
217   /* Arguments allocation */                                                   \
218   V(CreateMappedArguments, AccumulatorUse::kWrite)                             \
219   V(CreateUnmappedArguments, AccumulatorUse::kWrite)                           \
220   V(CreateRestParameter, AccumulatorUse::kWrite)                               \
221                                                                                \
222   /* Control Flow */                                                           \
223   V(Jump, AccumulatorUse::kNone, OperandType::kImm)                            \
224   V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx)                    \
225   V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm)                      \
226   V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
227   V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm)                     \
228   V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)             \
229   V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm)             \
230   V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)     \
231   V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm)            \
232   V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)    \
233   V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm)                      \
234   V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
235   V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm)                 \
236   V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx)         \
237   V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm)                   \
238   V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx)           \
239                                                                                \
240   /* Complex flow control For..in */                                           \
241   V(ForInPrepare, AccumulatorUse::kRead, OperandType::kRegOutTriple)           \
242   V(ForInDone, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg)   \
243   V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg,   \
244     OperandType::kRegPair, OperandType::kIdx)                                  \
245   V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg)                      \
246                                                                                \
247   /* Perform a stack guard check */                                            \
248   V(StackCheck, AccumulatorUse::kNone)                                         \
249                                                                                \
250   /* Non-local flow control */                                                 \
251   V(Throw, AccumulatorUse::kRead)                                              \
252   V(ReThrow, AccumulatorUse::kRead)                                            \
253   V(Return, AccumulatorUse::kRead)                                             \
254                                                                                \
255   /* Generators */                                                             \
256   V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg)                \
257   V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg)                \
258                                                                                \
259   /* Debugger */                                                               \
260   V(Debugger, AccumulatorUse::kNone)                                           \
261   DEBUG_BREAK_BYTECODE_LIST(V)                                                 \
262                                                                                \
263   /* Illegal bytecode (terminates execution) */                                \
264   V(Illegal, AccumulatorUse::kNone)                                            \
265                                                                                \
266   /* No operation (used to maintain source positions for peephole */           \
267   /* eliminated bytecodes). */                                                 \
268   V(Nop, AccumulatorUse::kNone)
269 
270 enum class AccumulatorUse : uint8_t {
271   kNone = 0,
272   kRead = 1 << 0,
273   kWrite = 1 << 1,
274   kReadWrite = kRead | kWrite
275 };
276 
277 V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
278   int result = static_cast<int>(lhs) & static_cast<int>(rhs);
279   return static_cast<AccumulatorUse>(result);
280 }
281 
282 V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
283   int result = static_cast<int>(lhs) | static_cast<int>(rhs);
284   return static_cast<AccumulatorUse>(result);
285 }
286 
287 // Enumeration of scaling factors applicable to scalable operands. Code
288 // relies on being able to cast values to integer scaling values.
289 #define OPERAND_SCALE_LIST(V) \
290   V(Single, 1)                \
291   V(Double, 2)                \
292   V(Quadruple, 4)
293 
294 enum class OperandScale : uint8_t {
295 #define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
296   OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
297 #undef DECLARE_OPERAND_SCALE
298       kLast = kQuadruple
299 };
300 
301 // Enumeration of the size classes of operand types used by
302 // bytecodes. Code relies on being able to cast values to integer
303 // types to get the size in bytes.
304 enum class OperandSize : uint8_t {
305   kNone = 0,
306   kByte = 1,
307   kShort = 2,
308   kQuad = 4,
309   kLast = kQuad
310 };
311 
312 // Primitive operand info used that summarize properties of operands.
313 // Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
314 #define OPERAND_TYPE_INFO_LIST(V)                         \
315   V(None, false, false, OperandSize::kNone)               \
316   V(ScalableSignedByte, true, false, OperandSize::kByte)  \
317   V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
318   V(FixedUnsignedByte, false, true, OperandSize::kByte)   \
319   V(FixedUnsignedShort, false, true, OperandSize::kShort)
320 
321 enum class OperandTypeInfo : uint8_t {
322 #define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
323   OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
324 #undef DECLARE_OPERAND_TYPE_INFO
325 };
326 
327 // Enumeration of operand types used by bytecodes.
328 enum class OperandType : uint8_t {
329 #define DECLARE_OPERAND_TYPE(Name, _) k##Name,
330   OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
331 #undef DECLARE_OPERAND_TYPE
332 #define COUNT_OPERAND_TYPES(x, _) +1
333   // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
334   // evaluate to the same value as the last operand.
335   kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
336 #undef COUNT_OPERAND_TYPES
337 };
338 
339 
340 // Enumeration of interpreter bytecodes.
341 enum class Bytecode : uint8_t {
342 #define DECLARE_BYTECODE(Name, ...) k##Name,
343   BYTECODE_LIST(DECLARE_BYTECODE)
344 #undef DECLARE_BYTECODE
345 #define COUNT_BYTECODE(x, ...) +1
346   // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
347   // evaluate to the same value as the last real bytecode.
348   kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
349 #undef COUNT_BYTECODE
350 };
351 
352 
353 // An interpreter Register which is located in the function's Register file
354 // in its stack-frame. Register hold parameters, this, and expression values.
355 class Register final {
356  public:
index_(index)357   explicit Register(int index = kInvalidIndex) : index_(index) {}
358 
index()359   int index() const { return index_; }
is_parameter()360   bool is_parameter() const { return index() < 0; }
is_valid()361   bool is_valid() const { return index_ != kInvalidIndex; }
362 
363   static Register FromParameterIndex(int index, int parameter_count);
364   int ToParameterIndex(int parameter_count) const;
365 
366   // Returns an invalid register.
invalid_value()367   static Register invalid_value() { return Register(); }
368 
369   // Returns the register for the function's closure object.
370   static Register function_closure();
371   bool is_function_closure() const;
372 
373   // Returns the register which holds the current context object.
374   static Register current_context();
375   bool is_current_context() const;
376 
377   // Returns the register for the incoming new target value.
378   static Register new_target();
379   bool is_new_target() const;
380 
381   // Returns the register for the bytecode array.
382   static Register bytecode_array();
383   bool is_bytecode_array() const;
384 
385   // Returns the register for the saved bytecode offset.
386   static Register bytecode_offset();
387   bool is_bytecode_offset() const;
388 
389   // Returns a register that can be used to represent the accumulator
390   // within code in the interpreter, but should never be emitted in
391   // bytecode.
392   static Register virtual_accumulator();
393 
394   OperandSize SizeOfOperand() const;
395 
ToOperand()396   int32_t ToOperand() const { return kRegisterFileStartOffset - index_; }
FromOperand(int32_t operand)397   static Register FromOperand(int32_t operand) {
398     return Register(kRegisterFileStartOffset - operand);
399   }
400 
401   static bool AreContiguous(Register reg1, Register reg2,
402                             Register reg3 = Register(),
403                             Register reg4 = Register(),
404                             Register reg5 = Register());
405 
406   std::string ToString(int parameter_count);
407 
408   bool operator==(const Register& other) const {
409     return index() == other.index();
410   }
411   bool operator!=(const Register& other) const {
412     return index() != other.index();
413   }
414   bool operator<(const Register& other) const {
415     return index() < other.index();
416   }
417   bool operator<=(const Register& other) const {
418     return index() <= other.index();
419   }
420   bool operator>(const Register& other) const {
421     return index() > other.index();
422   }
423   bool operator>=(const Register& other) const {
424     return index() >= other.index();
425   }
426 
427  private:
428   static const int kInvalidIndex = kMaxInt;
429   static const int kRegisterFileStartOffset =
430       InterpreterFrameConstants::kRegisterFileFromFp / kPointerSize;
431 
432   void* operator new(size_t size);
433   void operator delete(void* p);
434 
435   int index_;
436 };
437 
438 
439 class Bytecodes {
440  public:
441   // Returns string representation of |bytecode|.
442   static const char* ToString(Bytecode bytecode);
443 
444   // Returns string representation of |bytecode|.
445   static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
446 
447   // Returns string representation of |accumulator_use|.
448   static const char* AccumulatorUseToString(AccumulatorUse accumulator_use);
449 
450   // Returns string representation of |operand_type|.
451   static const char* OperandTypeToString(OperandType operand_type);
452 
453   // Returns string representation of |operand_scale|.
454   static const char* OperandScaleToString(OperandScale operand_scale);
455 
456   // Returns string representation of |operand_size|.
457   static const char* OperandSizeToString(OperandSize operand_size);
458 
459   // Returns byte value of bytecode.
ToByte(Bytecode bytecode)460   static uint8_t ToByte(Bytecode bytecode) {
461     DCHECK_LE(bytecode, Bytecode::kLast);
462     return static_cast<uint8_t>(bytecode);
463   }
464 
465   // Returns bytecode for |value|.
466   static Bytecode FromByte(uint8_t value);
467 
468   // Returns the number of operands expected by |bytecode|.
469   static int NumberOfOperands(Bytecode bytecode);
470 
471   // Returns the number of register operands expected by |bytecode|.
472   static int NumberOfRegisterOperands(Bytecode bytecode);
473 
474   // Returns the prefix bytecode representing an operand scale to be
475   // applied to a a bytecode.
476   static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale);
477 
478   // Returns true if the operand scale requires a prefix bytecode.
479   static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale);
480 
481   // Returns the scaling applied to scalable operands if bytecode is
482   // is a scaling prefix.
483   static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode);
484 
485   // Returns how accumulator is used by |bytecode|.
486   static AccumulatorUse GetAccumulatorUse(Bytecode bytecode);
487 
488   // Returns true if |bytecode| reads the accumulator.
489   static bool ReadsAccumulator(Bytecode bytecode);
490 
491   // Returns true if |bytecode| writes the accumulator.
492   static bool WritesAccumulator(Bytecode bytecode);
493 
494   // Return true if |bytecode| writes the accumulator with a boolean value.
495   static bool WritesBooleanToAccumulator(Bytecode bytecode);
496 
497   // Return true if |bytecode| is an accumulator load without effects,
498   // e.g. LdaConstant, LdaTrue, Ldar.
499   static bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode);
500 
501   // Return true if |bytecode| is a jump without effects,
502   // e.g.  any jump excluding those that include type coercion like
503   // JumpIfTrueToBoolean.
504   static bool IsJumpWithoutEffects(Bytecode bytecode);
505 
506   // Return true if |bytecode| is a register load without effects,
507   // e.g. Mov, Star, LdrUndefined.
508   static bool IsRegisterLoadWithoutEffects(Bytecode bytecode);
509 
510   // Returns true if |bytecode| has no effects.
511   static bool IsWithoutExternalSideEffects(Bytecode bytecode);
512 
513   // Returns the i-th operand of |bytecode|.
514   static OperandType GetOperandType(Bytecode bytecode, int i);
515 
516   // Returns a pointer to an array of operand types terminated in
517   // OperandType::kNone.
518   static const OperandType* GetOperandTypes(Bytecode bytecode);
519 
520   // Returns a pointer to an array of operand type info terminated in
521   // OperandTypeInfo::kNone.
522   static const OperandTypeInfo* GetOperandTypeInfos(Bytecode bytecode);
523 
524   // Returns the size of the i-th operand of |bytecode|.
525   static OperandSize GetOperandSize(Bytecode bytecode, int i,
526                                     OperandScale operand_scale);
527 
528   // Returns a pointer to an array of the operand sizes for |bytecode|.
529   static const OperandSize* GetOperandSizes(Bytecode bytecode,
530                                             OperandScale operand_scale);
531 
532   // Returns the offset of the i-th operand of |bytecode| relative to the start
533   // of the bytecode.
534   static int GetOperandOffset(Bytecode bytecode, int i,
535                               OperandScale operand_scale);
536 
537   // Returns a zero-based bitmap of the register operand positions of
538   // |bytecode|.
539   static int GetRegisterOperandBitmap(Bytecode bytecode);
540 
541   // Returns a debug break bytecode to replace |bytecode|.
542   static Bytecode GetDebugBreak(Bytecode bytecode);
543 
544   // Returns the size of the bytecode including its operands for the
545   // given |operand_scale|.
546   static int Size(Bytecode bytecode, OperandScale operand_scale);
547 
548   // Returns the size of |operand|.
549   static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
550 
551   // Returns the number of values which |bytecode| returns.
552   static size_t ReturnCount(Bytecode bytecode);
553 
554   // Returns true if the bytecode is a conditional jump taking
555   // an immediate byte operand (OperandType::kImm).
556   static bool IsConditionalJumpImmediate(Bytecode bytecode);
557 
558   // Returns true if the bytecode is a conditional jump taking
559   // a constant pool entry (OperandType::kIdx).
560   static bool IsConditionalJumpConstant(Bytecode bytecode);
561 
562   // Returns true if the bytecode is a conditional jump taking
563   // any kind of operand.
564   static bool IsConditionalJump(Bytecode bytecode);
565 
566   // Returns true if the bytecode is a jump or a conditional jump taking
567   // an immediate byte operand (OperandType::kImm).
568   static bool IsJumpImmediate(Bytecode bytecode);
569 
570   // Returns true if the bytecode is a jump or conditional jump taking a
571   // constant pool entry (OperandType::kIdx).
572   static bool IsJumpConstant(Bytecode bytecode);
573 
574   // Returns true if the bytecode is a jump or conditional jump taking
575   // any kind of operand.
576   static bool IsJump(Bytecode bytecode);
577 
578   // Returns true if the bytecode is a jump that internally coerces the
579   // accumulator to a boolean.
580   static bool IsJumpIfToBoolean(Bytecode bytecode);
581 
582   // Returns the equivalent jump bytecode without the accumulator coercion.
583   static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
584 
585   // Returns true if the bytecode is a conditional jump, a jump, or a return.
586   static bool IsJumpOrReturn(Bytecode bytecode);
587 
588   // Returns true if the bytecode is a call or a constructor call.
589   static bool IsCallOrNew(Bytecode bytecode);
590 
591   // Returns true if the bytecode is a call to the runtime.
592   static bool IsCallRuntime(Bytecode bytecode);
593 
594   // Returns true if the bytecode is a debug break.
595   static bool IsDebugBreak(Bytecode bytecode);
596 
597   // Returns true if the bytecode is Ldar or Star.
598   static bool IsLdarOrStar(Bytecode bytecode);
599 
600   // Returns true if the bytecode has wider operand forms.
601   static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
602 
603   // Returns true if the bytecode is a scaling prefix bytecode.
604   static bool IsPrefixScalingBytecode(Bytecode bytecode);
605 
606   // Returns true if |operand_type| is any type of register operand.
607   static bool IsRegisterOperandType(OperandType operand_type);
608 
609   // Returns true if |operand_type| represents a register used as an input.
610   static bool IsRegisterInputOperandType(OperandType operand_type);
611 
612   // Returns true if |operand_type| represents a register used as an output.
613   static bool IsRegisterOutputOperandType(OperandType operand_type);
614 
615   // Returns the number of registers represented by a register operand. For
616   // instance, a RegPair represents two registers.
617   static int GetNumberOfRegistersRepresentedBy(OperandType operand_type);
618 
619   // Returns true if |operand_type| is a maybe register operand
620   // (kMaybeReg).
621   static bool IsMaybeRegisterOperandType(OperandType operand_type);
622 
623   // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
624   static bool IsRuntimeIdOperandType(OperandType operand_type);
625 
626   // Returns true if |operand_type| is unsigned, false if signed.
627   static bool IsUnsignedOperandType(OperandType operand_type);
628 
629   // Decodes a register operand in a byte array.
630   static Register DecodeRegisterOperand(const uint8_t* operand_start,
631                                         OperandType operand_type,
632                                         OperandScale operand_scale);
633 
634   // Decodes a signed operand in a byte array.
635   static int32_t DecodeSignedOperand(const uint8_t* operand_start,
636                                      OperandType operand_type,
637                                      OperandScale operand_scale);
638 
639   // Decodes an unsigned operand in a byte array.
640   static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
641                                         OperandType operand_type,
642                                         OperandScale operand_scale);
643 
644   // Decode a single bytecode and operands to |os|.
645   static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
646                               int number_of_parameters);
647 
648   // Returns true if a handler is generated for a bytecode at a given
649   // operand scale. All bytecodes have handlers at OperandScale::kSingle,
650   // but only bytecodes with scalable operands have handlers with larger
651   // OperandScale values.
652   static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
653 
654   // Return the operand size required to hold a signed operand.
655   static OperandSize SizeForSignedOperand(int value);
656 
657   // Return the operand size required to hold an unsigned operand.
658   static OperandSize SizeForUnsignedOperand(uint32_t value);
659 
660  private:
661   DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes);
662 };
663 
664 class CreateObjectLiteralFlags {
665  public:
666   class FlagsBits : public BitField8<int, 0, 3> {};
667   class FastClonePropertiesCountBits
668       : public BitField8<int, FlagsBits::kNext, 3> {};
669   STATIC_ASSERT((FlagsBits::kMask & FastClonePropertiesCountBits::kMask) == 0);
670 };
671 
672 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode);
673 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use);
674 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale);
675 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size);
676 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
677 
678 }  // namespace interpreter
679 }  // namespace internal
680 }  // namespace v8
681 
682 #endif  // V8_INTERPRETER_BYTECODES_H_
683