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