5 #ifndef V8_INTERPRETER_BYTECODES_H_ 6 #define V8_INTERPRETER_BYTECODES_H_ 13 #include "src/globals.h" 14 #include "src/interpreter/bytecode-operands.h" 22 namespace interpreter {
26 #define BYTECODE_LIST(V) \ 28 V(Wide, AccumulatorUse::kNone) \ 29 V(ExtraWide, AccumulatorUse::kNone) \ 33 V(DebugBreakWide, AccumulatorUse::kReadWrite) \ 34 V(DebugBreakExtraWide, AccumulatorUse::kReadWrite) \ 35 V(DebugBreak0, AccumulatorUse::kReadWrite) \ 36 V(DebugBreak1, AccumulatorUse::kReadWrite, OperandType::kReg) \ 37 V(DebugBreak2, AccumulatorUse::kReadWrite, OperandType::kReg, \ 39 V(DebugBreak3, AccumulatorUse::kReadWrite, OperandType::kReg, \ 40 OperandType::kReg, OperandType::kReg) \ 41 V(DebugBreak4, AccumulatorUse::kReadWrite, OperandType::kReg, \ 42 OperandType::kReg, OperandType::kReg, OperandType::kReg) \ 43 V(DebugBreak5, AccumulatorUse::kReadWrite, OperandType::kRuntimeId, \ 44 OperandType::kReg, OperandType::kReg) \ 45 V(DebugBreak6, AccumulatorUse::kReadWrite, OperandType::kRuntimeId, \ 46 OperandType::kReg, OperandType::kReg, OperandType::kReg) \ 49 V(LdaZero, AccumulatorUse::kWrite) \ 50 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \ 51 V(LdaUndefined, AccumulatorUse::kWrite) \ 52 V(LdaNull, AccumulatorUse::kWrite) \ 53 V(LdaTheHole, AccumulatorUse::kWrite) \ 54 V(LdaTrue, AccumulatorUse::kWrite) \ 55 V(LdaFalse, AccumulatorUse::kWrite) \ 56 V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx) \ 59 V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx, OperandType::kIdx) \ 60 V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx, \ 62 V(StaGlobal, AccumulatorUse::kRead, OperandType::kIdx, OperandType::kIdx) \ 65 V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut) \ 66 V(PopContext, AccumulatorUse::kNone, OperandType::kReg) \ 67 V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \ 68 OperandType::kIdx, OperandType::kUImm) \ 69 V(LdaImmutableContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \ 70 OperandType::kIdx, OperandType::kUImm) \ 71 V(LdaCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx) \ 72 V(LdaImmutableCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx) \ 73 V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \ 74 OperandType::kIdx, OperandType::kUImm) \ 75 V(StaCurrentContextSlot, AccumulatorUse::kRead, OperandType::kIdx) \ 78 V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx) \ 79 V(LdaLookupContextSlot, AccumulatorUse::kWrite, OperandType::kIdx, \ 80 OperandType::kIdx, OperandType::kUImm) \ 81 V(LdaLookupGlobalSlot, AccumulatorUse::kWrite, OperandType::kIdx, \ 82 OperandType::kIdx, OperandType::kUImm) \ 83 V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \ 84 V(LdaLookupContextSlotInsideTypeof, AccumulatorUse::kWrite, \ 85 OperandType::kIdx, OperandType::kIdx, OperandType::kUImm) \ 86 V(LdaLookupGlobalSlotInsideTypeof, AccumulatorUse::kWrite, \ 87 OperandType::kIdx, OperandType::kIdx, OperandType::kUImm) \ 88 V(StaLookupSlot, AccumulatorUse::kReadWrite, OperandType::kIdx, \ 89 OperandType::kFlag8) \ 92 V(Ldar, AccumulatorUse::kWrite, OperandType::kReg) \ 93 V(Star, AccumulatorUse::kRead, OperandType::kRegOut) \ 96 V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut) \ 99 V(LdaNamedProperty, AccumulatorUse::kWrite, OperandType::kReg, \ 100 OperandType::kIdx, OperandType::kIdx) \ 101 V(LdaNamedPropertyNoFeedback, AccumulatorUse::kWrite, OperandType::kReg, \ 103 V(LdaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg, \ 107 V(LdaModuleVariable, AccumulatorUse::kWrite, OperandType::kImm, \ 108 OperandType::kUImm) \ 109 V(StaModuleVariable, AccumulatorUse::kRead, OperandType::kImm, \ 110 OperandType::kUImm) \ 113 V(StaNamedProperty, AccumulatorUse::kReadWrite, OperandType::kReg, \ 114 OperandType::kIdx, OperandType::kIdx) \ 115 V(StaNamedPropertyNoFeedback, AccumulatorUse::kReadWrite, OperandType::kReg, \ 116 OperandType::kIdx, OperandType::kFlag8) \ 117 V(StaNamedOwnProperty, AccumulatorUse::kReadWrite, OperandType::kReg, \ 118 OperandType::kIdx, OperandType::kIdx) \ 119 V(StaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg, \ 120 OperandType::kReg, OperandType::kIdx) \ 121 V(StaInArrayLiteral, AccumulatorUse::kReadWrite, OperandType::kReg, \ 122 OperandType::kReg, OperandType::kIdx) \ 123 V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \ 124 OperandType::kReg, OperandType::kFlag8, OperandType::kIdx) \ 125 V(CollectTypeProfile, AccumulatorUse::kRead, OperandType::kImm) \ 128 V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ 129 V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ 130 V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ 131 V(Div, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ 132 V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ 133 V(Exp, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ 134 V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg, \ 136 V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg, \ 138 V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg, \ 140 V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg, \ 142 V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg, \ 144 V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg, \ 148 V(AddSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ 149 V(SubSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ 150 V(MulSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ 151 V(DivSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ 152 V(ModSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ 153 V(ExpSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ 154 V(BitwiseOrSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ 156 V(BitwiseXorSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ 158 V(BitwiseAndSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ 160 V(ShiftLeftSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ 162 V(ShiftRightSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ 164 V(ShiftRightLogicalSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ 168 V(Inc, AccumulatorUse::kReadWrite, OperandType::kIdx) \ 169 V(Dec, AccumulatorUse::kReadWrite, OperandType::kIdx) \ 170 V(Negate, AccumulatorUse::kReadWrite, OperandType::kIdx) \ 171 V(BitwiseNot, AccumulatorUse::kReadWrite, OperandType::kIdx) \ 172 V(ToBooleanLogicalNot, AccumulatorUse::kReadWrite) \ 173 V(LogicalNot, AccumulatorUse::kReadWrite) \ 174 V(TypeOf, AccumulatorUse::kReadWrite) \ 175 V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \ 176 V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg) \ 179 V(GetSuperConstructor, AccumulatorUse::kRead, OperandType::kRegOut) \ 182 V(CallAnyReceiver, AccumulatorUse::kWrite, OperandType::kReg, \ 183 OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ 184 V(CallProperty, AccumulatorUse::kWrite, OperandType::kReg, \ 185 OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ 186 V(CallProperty0, AccumulatorUse::kWrite, OperandType::kReg, \ 187 OperandType::kReg, OperandType::kIdx) \ 188 V(CallProperty1, AccumulatorUse::kWrite, OperandType::kReg, \ 189 OperandType::kReg, OperandType::kReg, OperandType::kIdx) \ 190 V(CallProperty2, AccumulatorUse::kWrite, OperandType::kReg, \ 191 OperandType::kReg, OperandType::kReg, OperandType::kReg, \ 193 V(CallUndefinedReceiver, AccumulatorUse::kWrite, OperandType::kReg, \ 194 OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ 195 V(CallUndefinedReceiver0, AccumulatorUse::kWrite, OperandType::kReg, \ 197 V(CallUndefinedReceiver1, AccumulatorUse::kWrite, OperandType::kReg, \ 198 OperandType::kReg, OperandType::kIdx) \ 199 V(CallUndefinedReceiver2, AccumulatorUse::kWrite, OperandType::kReg, \ 200 OperandType::kReg, OperandType::kReg, OperandType::kIdx) \ 201 V(CallNoFeedback, AccumulatorUse::kWrite, OperandType::kReg, \ 202 OperandType::kRegList, OperandType::kRegCount) \ 203 V(CallWithSpread, AccumulatorUse::kWrite, OperandType::kReg, \ 204 OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ 205 V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId, \ 206 OperandType::kRegList, OperandType::kRegCount) \ 207 V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId, \ 208 OperandType::kRegList, OperandType::kRegCount, OperandType::kRegOutPair) \ 209 V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kNativeContextIndex, \ 210 OperandType::kRegList, OperandType::kRegCount) \ 213 V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kIntrinsicId, \ 214 OperandType::kRegList, OperandType::kRegCount) \ 217 V(Construct, AccumulatorUse::kReadWrite, OperandType::kReg, \ 218 OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ 219 V(ConstructWithSpread, AccumulatorUse::kReadWrite, OperandType::kReg, \ 220 OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ 223 V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg, \ 225 V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg, \ 227 V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg, \ 229 V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg, \ 231 V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg, \ 233 V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg, \ 235 V(TestReferenceEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \ 236 V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg, \ 238 V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg) \ 239 V(TestUndetectable, AccumulatorUse::kReadWrite) \ 240 V(TestNull, AccumulatorUse::kReadWrite) \ 241 V(TestUndefined, AccumulatorUse::kReadWrite) \ 242 V(TestTypeOf, AccumulatorUse::kReadWrite, OperandType::kFlag8) \ 245 V(ToName, AccumulatorUse::kRead, OperandType::kRegOut) \ 246 V(ToNumber, AccumulatorUse::kReadWrite, OperandType::kIdx) \ 247 V(ToNumeric, AccumulatorUse::kReadWrite, OperandType::kIdx) \ 248 V(ToObject, AccumulatorUse::kRead, OperandType::kRegOut) \ 249 V(ToString, AccumulatorUse::kReadWrite) \ 252 V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \ 253 OperandType::kIdx, OperandType::kFlag8) \ 254 V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \ 255 OperandType::kIdx, OperandType::kFlag8) \ 256 V(CreateArrayFromIterable, AccumulatorUse::kReadWrite) \ 257 V(CreateEmptyArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx) \ 258 V(CreateObjectLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \ 259 OperandType::kIdx, OperandType::kFlag8) \ 260 V(CreateEmptyObjectLiteral, AccumulatorUse::kWrite) \ 261 V(CloneObject, AccumulatorUse::kWrite, OperandType::kReg, \ 262 OperandType::kFlag8, OperandType::kIdx) \ 265 V(GetTemplateObject, AccumulatorUse::kWrite, OperandType::kIdx, \ 269 V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx, \ 270 OperandType::kIdx, OperandType::kFlag8) \ 273 V(CreateBlockContext, AccumulatorUse::kWrite, OperandType::kIdx) \ 274 V(CreateCatchContext, AccumulatorUse::kWrite, OperandType::kReg, \ 276 V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kIdx, \ 277 OperandType::kUImm) \ 278 V(CreateEvalContext, AccumulatorUse::kWrite, OperandType::kIdx, \ 279 OperandType::kUImm) \ 280 V(CreateWithContext, AccumulatorUse::kWrite, OperandType::kReg, \ 284 V(CreateMappedArguments, AccumulatorUse::kWrite) \ 285 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \ 286 V(CreateRestParameter, AccumulatorUse::kWrite) \ 290 V(JumpLoop, AccumulatorUse::kNone, OperandType::kUImm, OperandType::kImm) \ 292 V(Jump, AccumulatorUse::kNone, OperandType::kUImm) \ 294 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \ 297 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 298 V(JumpIfNotNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 299 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 300 V(JumpIfNotUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 301 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 302 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 303 V(JumpIfJSReceiverConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 305 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 306 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ 309 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kUImm) \ 310 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kUImm) \ 312 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kUImm) \ 313 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kUImm) \ 314 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kUImm) \ 315 V(JumpIfNotNull, AccumulatorUse::kRead, OperandType::kUImm) \ 316 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kUImm) \ 317 V(JumpIfNotUndefined, AccumulatorUse::kRead, OperandType::kUImm) \ 318 V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kUImm) \ 321 V(SwitchOnSmiNoFeedback, AccumulatorUse::kRead, OperandType::kIdx, \ 322 OperandType::kUImm, OperandType::kImm) \ 325 V(ForInEnumerate, AccumulatorUse::kWrite, OperandType::kReg) \ 326 V(ForInPrepare, AccumulatorUse::kRead, OperandType::kRegOutTriple, \ 328 V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg, \ 330 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ 331 OperandType::kRegPair, OperandType::kIdx) \ 332 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \ 335 V(StackCheck, AccumulatorUse::kNone) \ 338 V(SetPendingMessage, AccumulatorUse::kReadWrite) \ 341 V(Throw, AccumulatorUse::kRead) \ 342 V(ReThrow, AccumulatorUse::kRead) \ 343 V(Return, AccumulatorUse::kRead) \ 344 V(ThrowReferenceErrorIfHole, AccumulatorUse::kRead, OperandType::kIdx) \ 345 V(ThrowSuperNotCalledIfHole, AccumulatorUse::kRead) \ 346 V(ThrowSuperAlreadyCalledIfNotHole, AccumulatorUse::kRead) \ 349 V(SwitchOnGeneratorState, AccumulatorUse::kNone, OperandType::kReg, \ 350 OperandType::kIdx, OperandType::kUImm) \ 351 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg, \ 352 OperandType::kRegList, OperandType::kRegCount, OperandType::kUImm) \ 353 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg, \ 354 OperandType::kRegOutList, OperandType::kRegCount) \ 357 V(Debugger, AccumulatorUse::kNone) \ 360 V(IncBlockCounter, AccumulatorUse::kNone, OperandType::kIdx) \ 363 V(Abort, AccumulatorUse::kNone, OperandType::kIdx) \ 366 V(Illegal, AccumulatorUse::kNone) 369 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ 378 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ 380 V(DebugBreakExtraWide) 382 #define DEBUG_BREAK_BYTECODE_LIST(V) \ 383 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ 384 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) 388 #define JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 392 #define JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) V(JumpConstant) 394 #define JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 395 V(JumpIfToBooleanTrue) \ 396 V(JumpIfToBooleanFalse) 398 #define JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ 399 V(JumpIfToBooleanTrueConstant) \ 400 V(JumpIfToBooleanFalseConstant) 402 #define JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 403 JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 409 V(JumpIfNotUndefined) \ 410 V(JumpIfJSReceiver) \ 412 #define JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ 413 JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ 414 V(JumpIfNullConstant) \ 415 V(JumpIfNotNullConstant) \ 416 V(JumpIfUndefinedConstant) \ 417 V(JumpIfNotUndefinedConstant) \ 418 V(JumpIfTrueConstant) \ 419 V(JumpIfFalseConstant) \ 420 V(JumpIfJSReceiverConstant) \ 422 #define JUMP_CONSTANT_BYTECODE_LIST(V) \ 423 JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ 424 JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) 426 #define JUMP_IMMEDIATE_BYTECODE_LIST(V) \ 427 JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 428 JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) 430 #define JUMP_TO_BOOLEAN_BYTECODE_LIST(V) \ 431 JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 432 JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) 434 #define JUMP_UNCONDITIONAL_BYTECODE_LIST(V) \ 435 JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 436 JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) 438 #define JUMP_CONDITIONAL_BYTECODE_LIST(V) \ 439 JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ 440 JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) 442 #define JUMP_FORWARD_BYTECODE_LIST(V) \ 445 JUMP_CONDITIONAL_BYTECODE_LIST(V) 447 #define JUMP_BYTECODE_LIST(V) \ 448 JUMP_FORWARD_BYTECODE_LIST(V) \ 451 #define RETURN_BYTECODE_LIST(V) \ 456 enum class Bytecode : uint8_t {
457 #define DECLARE_BYTECODE(Name, ...) k##Name, 458 BYTECODE_LIST(DECLARE_BYTECODE)
459 #undef DECLARE_BYTECODE 460 #define COUNT_BYTECODE(x, ...) +1 463 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
464 #undef COUNT_BYTECODE 470 static const int kMaxOperands = 5;
473 static const int kBytecodeCount =
static_cast<int>(Bytecode::kLast) + 1;
476 static const char* ToString(Bytecode bytecode);
480 static std::string ToString(Bytecode bytecode, OperandScale operand_scale,
481 const char* separator =
".");
484 static uint8_t ToByte(Bytecode bytecode) {
485 DCHECK_LE(bytecode, Bytecode::kLast);
486 return static_cast<uint8_t
>(bytecode);
490 static Bytecode FromByte(uint8_t value) {
491 Bytecode bytecode =
static_cast<Bytecode
>(value);
492 DCHECK_LE(bytecode, Bytecode::kLast);
498 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale) {
499 switch (operand_scale) {
500 case OperandScale::kQuadruple:
501 return Bytecode::kExtraWide;
502 case OperandScale::kDouble:
503 return Bytecode::kWide;
510 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
511 return operand_scale != OperandScale::kSingle;
516 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode) {
518 case Bytecode::kExtraWide:
519 case Bytecode::kDebugBreakExtraWide:
520 return OperandScale::kQuadruple;
521 case Bytecode::kWide:
522 case Bytecode::kDebugBreakWide:
523 return OperandScale::kDouble;
530 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) {
531 DCHECK_LE(bytecode, Bytecode::kLast);
532 return kAccumulatorUse[
static_cast<size_t>(bytecode)];
536 static bool ReadsAccumulator(Bytecode bytecode) {
537 return BytecodeOperands::ReadsAccumulator(GetAccumulatorUse(bytecode));
541 static bool WritesAccumulator(Bytecode bytecode) {
542 return BytecodeOperands::WritesAccumulator(GetAccumulatorUse(bytecode));
547 static constexpr
bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
548 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero ||
549 bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull ||
550 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
551 bytecode == Bytecode::kLdaUndefined ||
552 bytecode == Bytecode::kLdaTheHole ||
553 bytecode == Bytecode::kLdaConstant ||
554 bytecode == Bytecode::kLdaContextSlot ||
555 bytecode == Bytecode::kLdaCurrentContextSlot ||
556 bytecode == Bytecode::kLdaImmutableContextSlot ||
557 bytecode == Bytecode::kLdaImmutableCurrentContextSlot;
562 static constexpr
bool IsCompareWithoutEffects(Bytecode bytecode) {
563 return bytecode == Bytecode::kTestUndetectable ||
564 bytecode == Bytecode::kTestNull ||
565 bytecode == Bytecode::kTestUndefined ||
566 bytecode == Bytecode::kTestTypeOf;
571 static constexpr
bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
572 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
573 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
578 static constexpr
bool IsConditionalJumpImmediate(Bytecode bytecode) {
579 return bytecode >= Bytecode::kJumpIfToBooleanTrue &&
580 bytecode <= Bytecode::kJumpIfJSReceiver;
585 static constexpr
bool IsConditionalJumpConstant(Bytecode bytecode) {
586 return bytecode >= Bytecode::kJumpIfNullConstant &&
587 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
592 static constexpr
bool IsConditionalJump(Bytecode bytecode) {
593 return bytecode >= Bytecode::kJumpIfNullConstant &&
594 bytecode <= Bytecode::kJumpIfJSReceiver;
598 static constexpr
bool IsUnconditionalJump(Bytecode bytecode) {
599 return bytecode >= Bytecode::kJumpLoop &&
600 bytecode <= Bytecode::kJumpConstant;
605 static constexpr
bool IsJumpImmediate(Bytecode bytecode) {
606 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
607 IsConditionalJumpImmediate(bytecode);
612 static constexpr
bool IsJumpConstant(Bytecode bytecode) {
613 return bytecode >= Bytecode::kJumpConstant &&
614 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
619 static constexpr
bool IsJumpIfToBoolean(Bytecode bytecode) {
620 return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant &&
621 bytecode <= Bytecode::kJumpIfToBooleanFalse;
626 static constexpr
bool IsJump(Bytecode bytecode) {
627 return bytecode >= Bytecode::kJumpLoop &&
628 bytecode <= Bytecode::kJumpIfJSReceiver;
633 static constexpr
bool IsForwardJump(Bytecode bytecode) {
634 return bytecode >= Bytecode::kJump &&
635 bytecode <= Bytecode::kJumpIfJSReceiver;
641 static constexpr
bool IsJumpWithoutEffects(Bytecode bytecode) {
642 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
646 static constexpr
bool IsSwitch(Bytecode bytecode) {
647 return bytecode == Bytecode::kSwitchOnSmiNoFeedback ||
648 bytecode == Bytecode::kSwitchOnGeneratorState;
653 static constexpr
bool IsWithoutExternalSideEffects(Bytecode bytecode) {
654 return (IsAccumulatorLoadWithoutEffects(bytecode) ||
655 IsRegisterLoadWithoutEffects(bytecode) ||
656 IsCompareWithoutEffects(bytecode) ||
657 IsJumpWithoutEffects(bytecode) || IsSwitch(bytecode));
661 static constexpr
bool IsLdarOrStar(Bytecode bytecode) {
662 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
666 static constexpr
bool IsCallOrConstruct(Bytecode bytecode) {
667 return bytecode == Bytecode::kCallAnyReceiver ||
668 bytecode == Bytecode::kCallProperty ||
669 bytecode == Bytecode::kCallProperty0 ||
670 bytecode == Bytecode::kCallProperty1 ||
671 bytecode == Bytecode::kCallProperty2 ||
672 bytecode == Bytecode::kCallUndefinedReceiver ||
673 bytecode == Bytecode::kCallUndefinedReceiver0 ||
674 bytecode == Bytecode::kCallUndefinedReceiver1 ||
675 bytecode == Bytecode::kCallUndefinedReceiver2 ||
676 bytecode == Bytecode::kCallNoFeedback ||
677 bytecode == Bytecode::kConstruct ||
678 bytecode == Bytecode::kCallWithSpread ||
679 bytecode == Bytecode::kConstructWithSpread ||
680 bytecode == Bytecode::kCallJSRuntime;
684 static constexpr
bool IsCallRuntime(Bytecode bytecode) {
685 return bytecode == Bytecode::kCallRuntime ||
686 bytecode == Bytecode::kCallRuntimeForPair ||
687 bytecode == Bytecode::kInvokeIntrinsic;
693 static constexpr
bool IsOneShotBytecode(Bytecode bytecode) {
694 return bytecode == Bytecode::kCallNoFeedback ||
695 bytecode == Bytecode::kLdaNamedPropertyNoFeedback ||
696 bytecode == Bytecode::kStaNamedPropertyNoFeedback;
700 static constexpr
bool IsPrefixScalingBytecode(Bytecode bytecode) {
701 return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide ||
702 bytecode == Bytecode::kDebugBreakExtraWide ||
703 bytecode == Bytecode::kDebugBreakWide;
707 static constexpr
bool Returns(Bytecode bytecode) {
708 #define OR_BYTECODE(NAME) || bytecode == Bytecode::k##NAME 709 return false RETURN_BYTECODE_LIST(OR_BYTECODE);
714 static int NumberOfOperands(Bytecode bytecode) {
715 DCHECK_LE(bytecode, Bytecode::kLast);
716 return kOperandCount[
static_cast<size_t>(bytecode)];
720 static OperandType GetOperandType(Bytecode bytecode,
int i) {
721 DCHECK_LE(bytecode, Bytecode::kLast);
722 DCHECK_LT(
i, NumberOfOperands(bytecode));
724 return GetOperandTypes(bytecode)[
i];
729 static const OperandType* GetOperandTypes(Bytecode bytecode) {
730 DCHECK_LE(bytecode, Bytecode::kLast);
731 return kOperandTypes[
static_cast<size_t>(bytecode)];
734 static bool OperandIsScalableSignedByte(Bytecode bytecode,
736 DCHECK_LE(bytecode, Bytecode::kLast);
737 return kOperandTypeInfos[
static_cast<size_t>(bytecode)][operand_index] ==
738 OperandTypeInfo::kScalableSignedByte;
741 static bool OperandIsScalableUnsignedByte(Bytecode bytecode,
743 DCHECK_LE(bytecode, Bytecode::kLast);
744 return kOperandTypeInfos[
static_cast<size_t>(bytecode)][operand_index] ==
745 OperandTypeInfo::kScalableUnsignedByte;
748 static bool OperandIsScalable(Bytecode bytecode,
int operand_index) {
749 return OperandIsScalableSignedByte(bytecode, operand_index) ||
750 OperandIsScalableUnsignedByte(bytecode, operand_index);
754 static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
757 static OperandSize GetOperandSize(Bytecode bytecode,
int i,
758 OperandScale operand_scale) {
759 CHECK_LT(
i, NumberOfOperands(bytecode));
760 return GetOperandSizes(bytecode, operand_scale)[
i];
764 static const OperandSize* GetOperandSizes(Bytecode bytecode,
765 OperandScale operand_scale) {
766 DCHECK_LE(bytecode, Bytecode::kLast);
767 DCHECK_GE(operand_scale, OperandScale::kSingle);
768 DCHECK_LE(operand_scale, OperandScale::kLast);
769 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
770 OperandScale::kLast == OperandScale::kQuadruple);
771 int scale_index =
static_cast<int>(operand_scale) >> 1;
772 return kOperandSizes[scale_index][
static_cast<size_t>(bytecode)];
777 static int GetOperandOffset(Bytecode bytecode,
int i,
778 OperandScale operand_scale);
782 static int Size(Bytecode bytecode, OperandScale operand_scale) {
783 DCHECK_LE(bytecode, Bytecode::kLast);
784 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
785 OperandScale::kLast == OperandScale::kQuadruple);
786 int scale_index =
static_cast<int>(operand_scale) >> 1;
787 return kBytecodeSizes[scale_index][
static_cast<size_t>(bytecode)];
791 static Bytecode GetDebugBreak(Bytecode bytecode);
794 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
798 static bool MakesCallAlongCriticalPath(Bytecode bytecode);
801 static ConvertReceiverMode GetReceiverMode(Bytecode bytecode) {
802 DCHECK(IsCallOrConstruct(bytecode) ||
803 bytecode == Bytecode::kInvokeIntrinsic);
805 case Bytecode::kCallProperty:
806 case Bytecode::kCallProperty0:
807 case Bytecode::kCallProperty1:
808 case Bytecode::kCallProperty2:
809 return ConvertReceiverMode::kNotNullOrUndefined;
810 case Bytecode::kCallUndefinedReceiver:
811 case Bytecode::kCallUndefinedReceiver0:
812 case Bytecode::kCallUndefinedReceiver1:
813 case Bytecode::kCallUndefinedReceiver2:
814 case Bytecode::kCallJSRuntime:
815 return ConvertReceiverMode::kNullOrUndefined;
816 case Bytecode::kCallAnyReceiver:
817 case Bytecode::kCallNoFeedback:
818 case Bytecode::kConstruct:
819 case Bytecode::kCallWithSpread:
820 case Bytecode::kConstructWithSpread:
821 case Bytecode::kInvokeIntrinsic:
822 return ConvertReceiverMode::kAny;
829 static bool IsDebugBreak(Bytecode bytecode);
832 static bool IsRegisterOperandType(OperandType operand_type);
835 static bool IsRegisterInputOperandType(OperandType operand_type);
838 static bool IsRegisterOutputOperandType(OperandType operand_type);
841 static bool IsRegisterListOperandType(OperandType operand_type);
845 static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale);
851 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
852 switch (operand_type) {
853 case OperandType::kReg:
854 case OperandType::kRegOut:
856 case OperandType::kRegPair:
857 case OperandType::kRegOutPair:
859 case OperandType::kRegOutTriple:
861 case OperandType::kRegList:
862 case OperandType::kRegOutList:
871 static OperandSize SizeOfOperand(OperandType operand_type,
872 OperandScale operand_scale) {
873 DCHECK_LE(operand_type, OperandType::kLast);
874 DCHECK_GE(operand_scale, OperandScale::kSingle);
875 DCHECK_LE(operand_scale, OperandScale::kLast);
876 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
877 OperandScale::kLast == OperandScale::kQuadruple);
878 int scale_index =
static_cast<int>(operand_scale) >> 1;
879 return kOperandKindSizes[scale_index][
static_cast<size_t>(operand_type)];
883 static bool IsRuntimeIdOperandType(OperandType operand_type);
886 static bool IsUnsignedOperandType(OperandType operand_type);
892 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
895 static OperandScale ScaleForSignedOperand(int32_t value) {
896 if (value >= kMinInt8 && value <= kMaxInt8) {
897 return OperandScale::kSingle;
898 }
else if (value >= kMinInt16 && value <= kMaxInt16) {
899 return OperandScale::kDouble;
901 return OperandScale::kQuadruple;
906 static OperandScale ScaleForUnsignedOperand(
uint32_t value) {
907 if (value <= kMaxUInt8) {
908 return OperandScale::kSingle;
909 }
else if (value <= kMaxUInt16) {
910 return OperandScale::kDouble;
912 return OperandScale::kQuadruple;
917 static OperandSize SizeForUnsignedOperand(
uint32_t value) {
918 if (value <= kMaxUInt8) {
919 return OperandSize::kByte;
920 }
else if (value <= kMaxUInt16) {
921 return OperandSize::kShort;
923 return OperandSize::kQuad;
927 static Address bytecode_size_table_address() {
928 return reinterpret_cast<Address>(
const_cast<int*
>(&kBytecodeSizes[0][0]));
932 static const OperandType*
const kOperandTypes[];
933 static const OperandTypeInfo*
const kOperandTypeInfos[];
934 static const int kOperandCount[];
935 static const int kNumberOfRegisterOperands[];
936 static const AccumulatorUse kAccumulatorUse[];
937 static const bool kIsScalable[];
938 static const int kBytecodeSizes[3][kBytecodeCount];
939 static const OperandSize*
const kOperandSizes[3][kBytecodeCount];
940 static OperandSize
const 941 kOperandKindSizes[3][BytecodeOperands::kOperandTypeCount];
944 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
945 const Bytecode& bytecode);
951 #endif // V8_INTERPRETER_BYTECODES_H_