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