Home | History | Annotate | Download | only in interpreter
      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:
    357   explicit Register(int index = kInvalidIndex) : index_(index) {}
    358 
    359   int index() const { return index_; }
    360   bool is_parameter() const { return index() < 0; }
    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.
    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 
    396   int32_t ToOperand() const { return kRegisterFileStartOffset - index_; }
    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.
    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