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 <cstdint>
      9 #include <iosfwd>
     10 #include <string>
     11 
     12 #include "src/globals.h"
     13 #include "src/interpreter/bytecode-operands.h"
     14 
     15 // This interface and it's implementation are independent of the
     16 // libv8_base library as they are used by the interpreter and the
     17 // standalone mkpeephole table generator program.
     18 
     19 namespace v8 {
     20 namespace internal {
     21 namespace interpreter {
     22 
     23 // The list of bytecodes which are interpreted by the interpreter.
     24 // Format is V(<bytecode>, <accumulator_use>, <operands>).
     25 #define BYTECODE_LIST(V)                                                       \
     26   /* Extended width operands */                                                \
     27   V(Wide, AccumulatorUse::kNone)                                               \
     28   V(ExtraWide, AccumulatorUse::kNone)                                          \
     29                                                                                \
     30   /* Loading the accumulator */                                                \
     31   V(LdaZero, AccumulatorUse::kWrite)                                           \
     32   V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm)                         \
     33   V(LdaUndefined, AccumulatorUse::kWrite)                                      \
     34   V(LdaNull, AccumulatorUse::kWrite)                                           \
     35   V(LdaTheHole, AccumulatorUse::kWrite)                                        \
     36   V(LdaTrue, AccumulatorUse::kWrite)                                           \
     37   V(LdaFalse, AccumulatorUse::kWrite)                                          \
     38   V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx)                    \
     39                                                                                \
     40   /* Globals */                                                                \
     41   V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx)                      \
     42   V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx)          \
     43   V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx,                 \
     44     OperandType::kIdx)                                                         \
     45   V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx,                 \
     46     OperandType::kIdx)                                                         \
     47                                                                                \
     48   /* Context operations */                                                     \
     49   V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut)                  \
     50   V(PopContext, AccumulatorUse::kNone, OperandType::kReg)                      \
     51   V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg,                 \
     52     OperandType::kIdx, OperandType::kUImm)                                     \
     53   V(LdaCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx)          \
     54   V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg,                  \
     55     OperandType::kIdx, OperandType::kUImm)                                     \
     56   V(StaCurrentContextSlot, AccumulatorUse::kRead, OperandType::kIdx)           \
     57                                                                                \
     58   /* Load-Store lookup slots */                                                \
     59   V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx)                  \
     60   V(LdaLookupContextSlot, AccumulatorUse::kWrite, OperandType::kIdx,           \
     61     OperandType::kIdx, OperandType::kUImm)                                     \
     62   V(LdaLookupGlobalSlot, AccumulatorUse::kWrite, OperandType::kIdx,            \
     63     OperandType::kIdx, OperandType::kUImm)                                     \
     64   V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx)      \
     65   V(LdaLookupContextSlotInsideTypeof, AccumulatorUse::kWrite,                  \
     66     OperandType::kIdx, OperandType::kIdx, OperandType::kUImm)                  \
     67   V(LdaLookupGlobalSlotInsideTypeof, AccumulatorUse::kWrite,                   \
     68     OperandType::kIdx, OperandType::kIdx, OperandType::kUImm)                  \
     69   V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx)        \
     70   V(StaLookupSlotStrict, AccumulatorUse::kReadWrite, OperandType::kIdx)        \
     71                                                                                \
     72   /* Register-accumulator transfers */                                         \
     73   V(Ldar, AccumulatorUse::kWrite, OperandType::kReg)                           \
     74   V(Star, AccumulatorUse::kRead, OperandType::kRegOut)                         \
     75                                                                                \
     76   /* Register-register transfers */                                            \
     77   V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut)       \
     78                                                                                \
     79   /* Property loads (LoadIC) operations */                                     \
     80   V(LdaNamedProperty, AccumulatorUse::kWrite, OperandType::kReg,               \
     81     OperandType::kIdx, OperandType::kIdx)                                      \
     82   V(LdaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg,           \
     83     OperandType::kIdx)                                                         \
     84                                                                                \
     85   /* Operations on module variables */                                         \
     86   V(LdaModuleVariable, AccumulatorUse::kWrite, OperandType::kImm,              \
     87     OperandType::kUImm)                                                        \
     88   V(StaModuleVariable, AccumulatorUse::kRead, OperandType::kImm,               \
     89     OperandType::kUImm)                                                        \
     90                                                                                \
     91   /* Propery stores (StoreIC) operations */                                    \
     92   V(StaNamedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg,          \
     93     OperandType::kIdx, OperandType::kIdx)                                      \
     94   V(StaNamedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg,          \
     95     OperandType::kIdx, OperandType::kIdx)                                      \
     96   V(StaKeyedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg,          \
     97     OperandType::kReg, OperandType::kIdx)                                      \
     98   V(StaKeyedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg,          \
     99     OperandType::kReg, OperandType::kIdx)                                      \
    100                                                                                \
    101   /* Binary Operators */                                                       \
    102   V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
    103   V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
    104   V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
    105   V(Div, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
    106   V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
    107   V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
    108     OperandType::kIdx)                                                         \
    109   V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
    110     OperandType::kIdx)                                                         \
    111   V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
    112     OperandType::kIdx)                                                         \
    113   V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
    114     OperandType::kIdx)                                                         \
    115   V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
    116     OperandType::kIdx)                                                         \
    117   V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg,          \
    118     OperandType::kIdx)                                                         \
    119                                                                                \
    120   /* Binary operators with immediate operands */                               \
    121   V(AddSmi, AccumulatorUse::kWrite, OperandType::kImm, OperandType::kReg,      \
    122     OperandType::kIdx)                                                         \
    123   V(SubSmi, AccumulatorUse::kWrite, OperandType::kImm, OperandType::kReg,      \
    124     OperandType::kIdx)                                                         \
    125   V(BitwiseOrSmi, AccumulatorUse::kWrite, OperandType::kImm,                   \
    126     OperandType::kReg, OperandType::kIdx)                                      \
    127   V(BitwiseAndSmi, AccumulatorUse::kWrite, OperandType::kImm,                  \
    128     OperandType::kReg, OperandType::kIdx)                                      \
    129   V(ShiftLeftSmi, AccumulatorUse::kWrite, OperandType::kImm,                   \
    130     OperandType::kReg, OperandType::kIdx)                                      \
    131   V(ShiftRightSmi, AccumulatorUse::kWrite, OperandType::kImm,                  \
    132     OperandType::kReg, OperandType::kIdx)                                      \
    133                                                                                \
    134   /* Unary Operators */                                                        \
    135   V(Inc, AccumulatorUse::kReadWrite, OperandType::kIdx)                        \
    136   V(Dec, AccumulatorUse::kReadWrite, OperandType::kIdx)                        \
    137   V(ToBooleanLogicalNot, AccumulatorUse::kReadWrite)                           \
    138   V(LogicalNot, AccumulatorUse::kReadWrite)                                    \
    139   V(TypeOf, AccumulatorUse::kReadWrite)                                        \
    140   V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg)       \
    141   V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg)       \
    142                                                                                \
    143   /* Call operations */                                                        \
    144   V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kRegList,    \
    145     OperandType::kRegCount, OperandType::kIdx)                                 \
    146   V(CallProperty, AccumulatorUse::kWrite, OperandType::kReg,                   \
    147     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
    148   V(TailCall, AccumulatorUse::kWrite, OperandType::kReg,                       \
    149     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
    150   V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId,              \
    151     OperandType::kRegList, OperandType::kRegCount)                             \
    152   V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId,        \
    153     OperandType::kRegList, OperandType::kRegCount, OperandType::kRegOutPair)   \
    154   V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kIdx,                  \
    155     OperandType::kRegList, OperandType::kRegCount)                             \
    156                                                                                \
    157   /* Intrinsics */                                                             \
    158   V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kIntrinsicId,        \
    159     OperandType::kRegList, OperandType::kRegCount)                             \
    160                                                                                \
    161   /* New operator */                                                           \
    162   V(New, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kRegList, \
    163     OperandType::kRegCount, OperandType::kIdx)                                 \
    164                                                                                \
    165   /* Test Operators */                                                         \
    166   V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
    167     OperandType::kIdx)                                                         \
    168   V(TestNotEqual, AccumulatorUse::kReadWrite, OperandType::kReg,               \
    169     OperandType::kIdx)                                                         \
    170   V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg,            \
    171     OperandType::kIdx)                                                         \
    172   V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg,               \
    173     OperandType::kIdx)                                                         \
    174   V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg,            \
    175     OperandType::kIdx)                                                         \
    176   V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg,        \
    177     OperandType::kIdx)                                                         \
    178   V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg,     \
    179     OperandType::kIdx)                                                         \
    180   V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg)             \
    181   V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg)                     \
    182                                                                                \
    183   /* Cast operators */                                                         \
    184   V(ToName, AccumulatorUse::kRead, OperandType::kRegOut)                       \
    185   V(ToNumber, AccumulatorUse::kRead, OperandType::kRegOut)                     \
    186   V(ToObject, AccumulatorUse::kRead, OperandType::kRegOut)                     \
    187                                                                                \
    188   /* Literals */                                                               \
    189   V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx,            \
    190     OperandType::kIdx, OperandType::kFlag8)                                    \
    191   V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx,             \
    192     OperandType::kIdx, OperandType::kFlag8)                                    \
    193   V(CreateObjectLiteral, AccumulatorUse::kNone, OperandType::kIdx,             \
    194     OperandType::kIdx, OperandType::kFlag8, OperandType::kRegOut)              \
    195                                                                                \
    196   /* Closure allocation */                                                     \
    197   V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx,                  \
    198     OperandType::kFlag8)                                                       \
    199                                                                                \
    200   /* Context allocation */                                                     \
    201   V(CreateBlockContext, AccumulatorUse::kReadWrite, OperandType::kIdx)         \
    202   V(CreateCatchContext, AccumulatorUse::kReadWrite, OperandType::kReg,         \
    203     OperandType::kIdx, OperandType::kIdx)                                      \
    204   V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kUImm)         \
    205   V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg,          \
    206     OperandType::kIdx)                                                         \
    207                                                                                \
    208   /* Arguments allocation */                                                   \
    209   V(CreateMappedArguments, AccumulatorUse::kWrite)                             \
    210   V(CreateUnmappedArguments, AccumulatorUse::kWrite)                           \
    211   V(CreateRestParameter, AccumulatorUse::kWrite)                               \
    212                                                                                \
    213   /* Control Flow */                                                           \
    214   V(Jump, AccumulatorUse::kNone, OperandType::kImm)                            \
    215   V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx)                    \
    216   V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm)                      \
    217   V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
    218   V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm)                     \
    219   V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)             \
    220   V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm)             \
    221   V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)     \
    222   V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm)            \
    223   V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)    \
    224   V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm)                      \
    225   V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
    226   V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm)                 \
    227   V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx)         \
    228   V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm)                   \
    229   V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx)           \
    230   V(JumpLoop, AccumulatorUse::kNone, OperandType::kImm, OperandType::kImm)     \
    231                                                                                \
    232   /* Complex flow control For..in */                                           \
    233   V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg,                    \
    234     OperandType::kRegOutTriple)                                                \
    235   V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg,                  \
    236     OperandType::kReg)                                                         \
    237   V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg,   \
    238     OperandType::kRegPair, OperandType::kIdx)                                  \
    239   V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg)                      \
    240                                                                                \
    241   /* Perform a stack guard check */                                            \
    242   V(StackCheck, AccumulatorUse::kNone)                                         \
    243                                                                                \
    244   /* Non-local flow control */                                                 \
    245   V(Throw, AccumulatorUse::kRead)                                              \
    246   V(ReThrow, AccumulatorUse::kRead)                                            \
    247   V(Return, AccumulatorUse::kRead)                                             \
    248                                                                                \
    249   /* Generators */                                                             \
    250   V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg)                \
    251   V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg)                \
    252                                                                                \
    253   /* Debugger */                                                               \
    254   V(Debugger, AccumulatorUse::kNone)                                           \
    255                                                                                \
    256   /* Debug Breakpoints - one for each possible size of unscaled bytecodes */   \
    257   /* and one for each operand widening prefix bytecode                    */   \
    258   V(DebugBreak0, AccumulatorUse::kRead)                                        \
    259   V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg)                     \
    260   V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg)  \
    261   V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg,  \
    262     OperandType::kReg)                                                         \
    263   V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg,  \
    264     OperandType::kReg, OperandType::kReg)                                      \
    265   V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId,               \
    266     OperandType::kReg, OperandType::kReg)                                      \
    267   V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId,               \
    268     OperandType::kReg, OperandType::kReg, OperandType::kReg)                   \
    269   V(DebugBreakWide, AccumulatorUse::kRead)                                     \
    270   V(DebugBreakExtraWide, AccumulatorUse::kRead)                                \
    271                                                                                \
    272   /* Illegal bytecode (terminates execution) */                                \
    273   V(Illegal, AccumulatorUse::kNone)                                            \
    274                                                                                \
    275   /* No operation (used to maintain source positions for peephole */           \
    276   /* eliminated bytecodes). */                                                 \
    277   V(Nop, AccumulatorUse::kNone)
    278 
    279 // List of debug break bytecodes.
    280 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
    281   V(DebugBreak0)                           \
    282   V(DebugBreak1)                           \
    283   V(DebugBreak2)                           \
    284   V(DebugBreak3)                           \
    285   V(DebugBreak4)                           \
    286   V(DebugBreak5)                           \
    287   V(DebugBreak6)
    288 
    289 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
    290   V(DebugBreakWide)                         \
    291   V(DebugBreakExtraWide)
    292 
    293 #define DEBUG_BREAK_BYTECODE_LIST(V) \
    294   DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
    295   DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
    296 
    297 // Enumeration of interpreter bytecodes.
    298 enum class Bytecode : uint8_t {
    299 #define DECLARE_BYTECODE(Name, ...) k##Name,
    300   BYTECODE_LIST(DECLARE_BYTECODE)
    301 #undef DECLARE_BYTECODE
    302 #define COUNT_BYTECODE(x, ...) +1
    303   // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
    304   // evaluate to the same value as the last real bytecode.
    305   kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
    306 #undef COUNT_BYTECODE
    307 };
    308 
    309 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
    310 // See crbug.com/603131.
    311 #if V8_CC_MSVC
    312 #define CONSTEXPR const
    313 #else
    314 #define CONSTEXPR constexpr
    315 #endif
    316 
    317 class V8_EXPORT_PRIVATE Bytecodes final {
    318  public:
    319   //  The maximum number of operands a bytecode may have.
    320   static const int kMaxOperands = 4;
    321 
    322   // Returns string representation of |bytecode|.
    323   static const char* ToString(Bytecode bytecode);
    324 
    325   // Returns string representation of |bytecode|.
    326   static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
    327 
    328   // Returns byte value of bytecode.
    329   static uint8_t ToByte(Bytecode bytecode) {
    330     DCHECK_LE(bytecode, Bytecode::kLast);
    331     return static_cast<uint8_t>(bytecode);
    332   }
    333 
    334   // Returns bytecode for |value|.
    335   static Bytecode FromByte(uint8_t value) {
    336     Bytecode bytecode = static_cast<Bytecode>(value);
    337     DCHECK(bytecode <= Bytecode::kLast);
    338     return bytecode;
    339   }
    340 
    341   // Returns the prefix bytecode representing an operand scale to be
    342   // applied to a a bytecode.
    343   static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale) {
    344     switch (operand_scale) {
    345       case OperandScale::kQuadruple:
    346         return Bytecode::kExtraWide;
    347       case OperandScale::kDouble:
    348         return Bytecode::kWide;
    349       default:
    350         UNREACHABLE();
    351         return Bytecode::kIllegal;
    352     }
    353   }
    354 
    355   // Returns true if the operand scale requires a prefix bytecode.
    356   static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
    357     return operand_scale != OperandScale::kSingle;
    358   }
    359 
    360   // Returns the scaling applied to scalable operands if bytecode is
    361   // is a scaling prefix.
    362   static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode) {
    363     switch (bytecode) {
    364       case Bytecode::kExtraWide:
    365       case Bytecode::kDebugBreakExtraWide:
    366         return OperandScale::kQuadruple;
    367       case Bytecode::kWide:
    368       case Bytecode::kDebugBreakWide:
    369         return OperandScale::kDouble;
    370       default:
    371         UNREACHABLE();
    372         return OperandScale::kSingle;
    373     }
    374   }
    375 
    376   // Returns how accumulator is used by |bytecode|.
    377   static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) {
    378     DCHECK(bytecode <= Bytecode::kLast);
    379     return kAccumulatorUse[static_cast<size_t>(bytecode)];
    380   }
    381 
    382   // Returns true if |bytecode| reads the accumulator.
    383   static bool ReadsAccumulator(Bytecode bytecode) {
    384     return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) ==
    385            AccumulatorUse::kRead;
    386   }
    387 
    388   // Returns true if |bytecode| writes the accumulator.
    389   static bool WritesAccumulator(Bytecode bytecode) {
    390     return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) ==
    391            AccumulatorUse::kWrite;
    392   }
    393 
    394   // Return true if |bytecode| writes the accumulator with a boolean value.
    395   static bool WritesBooleanToAccumulator(Bytecode bytecode) {
    396     switch (bytecode) {
    397       case Bytecode::kLdaTrue:
    398       case Bytecode::kLdaFalse:
    399       case Bytecode::kToBooleanLogicalNot:
    400       case Bytecode::kLogicalNot:
    401       case Bytecode::kTestEqual:
    402       case Bytecode::kTestNotEqual:
    403       case Bytecode::kTestEqualStrict:
    404       case Bytecode::kTestLessThan:
    405       case Bytecode::kTestLessThanOrEqual:
    406       case Bytecode::kTestGreaterThan:
    407       case Bytecode::kTestGreaterThanOrEqual:
    408       case Bytecode::kTestInstanceOf:
    409       case Bytecode::kTestIn:
    410       case Bytecode::kForInContinue:
    411         return true;
    412       default:
    413         return false;
    414     }
    415   }
    416 
    417   // Return true if |bytecode| is an accumulator load without effects,
    418   // e.g. LdaConstant, LdaTrue, Ldar.
    419   static CONSTEXPR bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
    420     return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero ||
    421            bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull ||
    422            bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
    423            bytecode == Bytecode::kLdaUndefined ||
    424            bytecode == Bytecode::kLdaTheHole ||
    425            bytecode == Bytecode::kLdaConstant ||
    426            bytecode == Bytecode::kLdaContextSlot ||
    427            bytecode == Bytecode::kLdaCurrentContextSlot;
    428   }
    429 
    430   // Return true if |bytecode| is a register load without effects,
    431   // e.g. Mov, Star.
    432   static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
    433     return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
    434            bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
    435   }
    436 
    437   // Returns true if the bytecode is a conditional jump taking
    438   // an immediate byte operand (OperandType::kImm).
    439   static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) {
    440     return bytecode == Bytecode::kJumpIfTrue ||
    441            bytecode == Bytecode::kJumpIfFalse ||
    442            bytecode == Bytecode::kJumpIfToBooleanTrue ||
    443            bytecode == Bytecode::kJumpIfToBooleanFalse ||
    444            bytecode == Bytecode::kJumpIfNotHole ||
    445            bytecode == Bytecode::kJumpIfNull ||
    446            bytecode == Bytecode::kJumpIfUndefined;
    447   }
    448 
    449   // Returns true if the bytecode is a conditional jump taking
    450   // a constant pool entry (OperandType::kIdx).
    451   static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) {
    452     return bytecode == Bytecode::kJumpIfTrueConstant ||
    453            bytecode == Bytecode::kJumpIfFalseConstant ||
    454            bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
    455            bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
    456            bytecode == Bytecode::kJumpIfNotHoleConstant ||
    457            bytecode == Bytecode::kJumpIfNullConstant ||
    458            bytecode == Bytecode::kJumpIfUndefinedConstant;
    459   }
    460 
    461   // Returns true if the bytecode is a conditional jump taking
    462   // any kind of operand.
    463   static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) {
    464     return IsConditionalJumpImmediate(bytecode) ||
    465            IsConditionalJumpConstant(bytecode);
    466   }
    467 
    468   // Returns true if the bytecode is a jump or a conditional jump taking
    469   // an immediate byte operand (OperandType::kImm).
    470   static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) {
    471     return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
    472            IsConditionalJumpImmediate(bytecode);
    473   }
    474 
    475   // Returns true if the bytecode is a jump or conditional jump taking a
    476   // constant pool entry (OperandType::kIdx).
    477   static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) {
    478     return bytecode == Bytecode::kJumpConstant ||
    479            IsConditionalJumpConstant(bytecode);
    480   }
    481 
    482   // Returns true if the bytecode is a jump that internally coerces the
    483   // accumulator to a boolean.
    484   static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) {
    485     return bytecode == Bytecode::kJumpIfToBooleanTrue ||
    486            bytecode == Bytecode::kJumpIfToBooleanFalse ||
    487            bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
    488            bytecode == Bytecode::kJumpIfToBooleanFalseConstant;
    489   }
    490 
    491   // Returns true if the bytecode is a jump or conditional jump taking
    492   // any kind of operand.
    493   static CONSTEXPR bool IsJump(Bytecode bytecode) {
    494     return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
    495   }
    496 
    497   // Returns true if the bytecode is a conditional jump, a jump, or a return.
    498   static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) {
    499     return bytecode == Bytecode::kReturn || IsJump(bytecode);
    500   }
    501 
    502   // Return true if |bytecode| is a jump without effects,
    503   // e.g.  any jump excluding those that include type coercion like
    504   // JumpIfTrueToBoolean.
    505   static CONSTEXPR bool IsJumpWithoutEffects(Bytecode bytecode) {
    506     return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
    507   }
    508 
    509   // Returns true if |bytecode| has no effects. These bytecodes only manipulate
    510   // interpreter frame state and will never throw.
    511   static CONSTEXPR bool IsWithoutExternalSideEffects(Bytecode bytecode) {
    512     return (IsAccumulatorLoadWithoutEffects(bytecode) ||
    513             IsRegisterLoadWithoutEffects(bytecode) ||
    514             bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
    515   }
    516 
    517   // Returns true if the bytecode is Ldar or Star.
    518   static CONSTEXPR bool IsLdarOrStar(Bytecode bytecode) {
    519     return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
    520   }
    521 
    522   // Returns true if |bytecode| puts a name in the accumulator.
    523   static CONSTEXPR bool PutsNameInAccumulator(Bytecode bytecode) {
    524     return bytecode == Bytecode::kTypeOf;
    525   }
    526 
    527   // Returns true if the bytecode is a call or a constructor call.
    528   static CONSTEXPR bool IsCallOrNew(Bytecode bytecode) {
    529     return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty ||
    530            bytecode == Bytecode::kTailCall || bytecode == Bytecode::kNew;
    531   }
    532 
    533   // Returns true if the bytecode is a call to the runtime.
    534   static CONSTEXPR bool IsCallRuntime(Bytecode bytecode) {
    535     return bytecode == Bytecode::kCallRuntime ||
    536            bytecode == Bytecode::kCallRuntimeForPair ||
    537            bytecode == Bytecode::kInvokeIntrinsic;
    538   }
    539 
    540   // Returns true if the bytecode is a scaling prefix bytecode.
    541   static CONSTEXPR bool IsPrefixScalingBytecode(Bytecode bytecode) {
    542     return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide ||
    543            bytecode == Bytecode::kDebugBreakExtraWide ||
    544            bytecode == Bytecode::kDebugBreakWide;
    545   }
    546 
    547   // Returns the number of values which |bytecode| returns.
    548   static CONSTEXPR size_t ReturnCount(Bytecode bytecode) {
    549     return bytecode == Bytecode::kReturn ? 1 : 0;
    550   }
    551 
    552   // Returns the number of operands expected by |bytecode|.
    553   static int NumberOfOperands(Bytecode bytecode) {
    554     DCHECK(bytecode <= Bytecode::kLast);
    555     return kOperandCount[static_cast<size_t>(bytecode)];
    556   }
    557 
    558   // Returns the i-th operand of |bytecode|.
    559   static OperandType GetOperandType(Bytecode bytecode, int i) {
    560     DCHECK_LE(bytecode, Bytecode::kLast);
    561     DCHECK_LT(i, NumberOfOperands(bytecode));
    562     DCHECK_GE(i, 0);
    563     return GetOperandTypes(bytecode)[i];
    564   }
    565 
    566   // Returns a pointer to an array of operand types terminated in
    567   // OperandType::kNone.
    568   static const OperandType* GetOperandTypes(Bytecode bytecode) {
    569     DCHECK(bytecode <= Bytecode::kLast);
    570     return kOperandTypes[static_cast<size_t>(bytecode)];
    571   }
    572 
    573   static bool OperandIsScalableSignedByte(Bytecode bytecode,
    574                                           int operand_index) {
    575     DCHECK(bytecode <= Bytecode::kLast);
    576     return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
    577            OperandTypeInfo::kScalableSignedByte;
    578   }
    579 
    580   static bool OperandIsScalableUnsignedByte(Bytecode bytecode,
    581                                             int operand_index) {
    582     DCHECK(bytecode <= Bytecode::kLast);
    583     return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
    584            OperandTypeInfo::kScalableUnsignedByte;
    585   }
    586 
    587   static bool OperandIsScalable(Bytecode bytecode, int operand_index) {
    588     return OperandIsScalableSignedByte(bytecode, operand_index) ||
    589            OperandIsScalableUnsignedByte(bytecode, operand_index);
    590   }
    591 
    592   // Returns true if the bytecode has wider operand forms.
    593   static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
    594 
    595   // Returns the size of the i-th operand of |bytecode|.
    596   static OperandSize GetOperandSize(Bytecode bytecode, int i,
    597                                     OperandScale operand_scale) {
    598     CHECK_LT(i, NumberOfOperands(bytecode));
    599     return GetOperandSizes(bytecode, operand_scale)[i];
    600   }
    601 
    602   // Returns the operand sizes of |bytecode| with scale |operand_scale|.
    603   static const OperandSize* GetOperandSizes(Bytecode bytecode,
    604                                             OperandScale operand_scale) {
    605     DCHECK(bytecode <= Bytecode::kLast);
    606     DCHECK_GE(operand_scale, OperandScale::kSingle);
    607     DCHECK_LE(operand_scale, OperandScale::kLast);
    608     STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
    609                   OperandScale::kLast == OperandScale::kQuadruple);
    610     int scale_index = static_cast<int>(operand_scale) >> 1;
    611     return kOperandSizes[static_cast<size_t>(bytecode)][scale_index];
    612   }
    613 
    614   // Returns the offset of the i-th operand of |bytecode| relative to the start
    615   // of the bytecode.
    616   static int GetOperandOffset(Bytecode bytecode, int i,
    617                               OperandScale operand_scale);
    618 
    619   // Returns the size of the bytecode including its operands for the
    620   // given |operand_scale|.
    621   static int Size(Bytecode bytecode, OperandScale operand_scale) {
    622     DCHECK(bytecode <= Bytecode::kLast);
    623     STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
    624                   OperandScale::kLast == OperandScale::kQuadruple);
    625     int scale_index = static_cast<int>(operand_scale) >> 1;
    626     return kBytecodeSizes[static_cast<size_t>(bytecode)][scale_index];
    627   }
    628 
    629   // Returns a debug break bytecode to replace |bytecode|.
    630   static Bytecode GetDebugBreak(Bytecode bytecode);
    631 
    632   // Returns the equivalent jump bytecode without the accumulator coercion.
    633   static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
    634 
    635   // Returns true if the bytecode is a debug break.
    636   static bool IsDebugBreak(Bytecode bytecode);
    637 
    638   // Returns true if |operand_type| is any type of register operand.
    639   static bool IsRegisterOperandType(OperandType operand_type);
    640 
    641   // Returns true if |operand_type| represents a register used as an input.
    642   static bool IsRegisterInputOperandType(OperandType operand_type);
    643 
    644   // Returns true if |operand_type| represents a register used as an output.
    645   static bool IsRegisterOutputOperandType(OperandType operand_type);
    646 
    647   // Returns true if the handler for |bytecode| should look ahead and inline a
    648   // dispatch to a Star bytecode.
    649   static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale);
    650 
    651   // Returns the number of registers represented by a register operand. For
    652   // instance, a RegPair represents two registers. Should not be called for
    653   // kRegList which has a variable number of registers based on the following
    654   // kRegCount operand.
    655   static int GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
    656     switch (operand_type) {
    657       case OperandType::kReg:
    658       case OperandType::kRegOut:
    659         return 1;
    660       case OperandType::kRegPair:
    661       case OperandType::kRegOutPair:
    662         return 2;
    663       case OperandType::kRegOutTriple:
    664         return 3;
    665       case OperandType::kRegList:
    666         UNREACHABLE();
    667         return 0;
    668       default:
    669         return 0;
    670     }
    671     return 0;
    672   }
    673 
    674   // Returns the size of |operand| for |operand_scale|.
    675   static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
    676 
    677   // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
    678   static bool IsRuntimeIdOperandType(OperandType operand_type);
    679 
    680   // Returns true if |operand_type| is unsigned, false if signed.
    681   static bool IsUnsignedOperandType(OperandType operand_type);
    682 
    683   // Returns true if a handler is generated for a bytecode at a given
    684   // operand scale. All bytecodes have handlers at OperandScale::kSingle,
    685   // but only bytecodes with scalable operands have handlers with larger
    686   // OperandScale values.
    687   static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
    688 
    689   // Return the operand scale required to hold a signed operand with |value|.
    690   static OperandScale ScaleForSignedOperand(int32_t value) {
    691     if (value >= kMinInt8 && value <= kMaxInt8) {
    692       return OperandScale::kSingle;
    693     } else if (value >= kMinInt16 && value <= kMaxInt16) {
    694       return OperandScale::kDouble;
    695     } else {
    696       return OperandScale::kQuadruple;
    697     }
    698   }
    699 
    700   // Return the operand scale required to hold an unsigned operand with |value|.
    701   static OperandScale ScaleForUnsignedOperand(uint32_t value) {
    702     if (value <= kMaxUInt8) {
    703       return OperandScale::kSingle;
    704     } else if (value <= kMaxUInt16) {
    705       return OperandScale::kDouble;
    706     } else {
    707       return OperandScale::kQuadruple;
    708     }
    709   }
    710 
    711   // Return the operand size required to hold an unsigned operand with |value|.
    712   static OperandSize SizeForUnsignedOperand(uint32_t value) {
    713     if (value <= kMaxUInt8) {
    714       return OperandSize::kByte;
    715     } else if (value <= kMaxUInt16) {
    716       return OperandSize::kShort;
    717     } else {
    718       return OperandSize::kQuad;
    719     }
    720   }
    721 
    722  private:
    723   static const OperandType* const kOperandTypes[];
    724   static const OperandTypeInfo* const kOperandTypeInfos[];
    725   static const int kOperandCount[];
    726   static const int kNumberOfRegisterOperands[];
    727   static const AccumulatorUse kAccumulatorUse[];
    728   static const bool kIsScalable[];
    729   static const int kBytecodeSizes[][3];
    730   static const OperandSize* const kOperandSizes[][3];
    731 };
    732 
    733 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
    734 // See crbug.com/603131.
    735 #undef CONSTEXPR
    736 
    737 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
    738                                            const Bytecode& bytecode);
    739 
    740 }  // namespace interpreter
    741 }  // namespace internal
    742 }  // namespace v8
    743 
    744 #endif  // V8_INTERPRETER_BYTECODES_H_
    745