Lines Matching defs:Bytecode
13 #include "src/interpreter/bytecode-operands.h"
24 // Format is V(<bytecode>, <accumulator_use>, <operands>).
292 /* and one for each operand widening prefix bytecode */ \
307 /* Illegal bytecode (terminates execution) */ \
396 enum class Bytecode : uint8_t {
402 // evaluate to the same value as the last real bytecode.
409 // The maximum number of operands a bytecode may have.
412 // Returns string representation of |bytecode|.
413 static const char* ToString(Bytecode bytecode);
415 // Returns string representation of |bytecode|.
416 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
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);
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;
431 // Returns the prefix bytecode representing an operand scale to be
432 // applied to a a bytecode.
433 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale) {
436 return Bytecode::kExtraWide;
438 return Bytecode::kWide;
441 return Bytecode::kIllegal;
445 // Returns true if the operand scale requires a prefix bytecode.
450 // Returns the scaling applied to scalable operands if bytecode is
452 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode) {
453 switch (bytecode) {
454 case Bytecode::kExtraWide:
455 case Bytecode::kDebugBreakExtraWide:
457 case Bytecode::kWide:
458 case Bytecode::kDebugBreakWide:
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)];
472 // Returns true if |bytecode| reads the accumulator.
473 static bool ReadsAccumulator(Bytecode bytecode) {
474 return BytecodeOperands::ReadsAccumulator(GetAccumulatorUse(bytecode));
477 // Returns true if |bytecode| writes the accumulator.
478 static bool WritesAccumulator(Bytecode bytecode) {
479 return BytecodeOperands::WritesAccumulator(GetAccumulatorUse(bytecode));
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:
508 // Return true if |bytecode| is an accumulator load without effects,
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;
523 // Return true if |bytecode| is a register load without effects,
525 static constexpr bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
526 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
527 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
530 // Returns true if the bytecode is a conditional jump taking
532 static constexpr bool IsConditionalJumpImmediate(Bytecode bytecode) {
533 return bytecode >= Bytecode::kJumpIfToBooleanTrue &&
534 bytecode <= Bytecode::kJumpIfNotHole;
537 // Returns true if the bytecode is a conditional jump taking
539 static constexpr bool IsConditionalJumpConstant(Bytecode bytecode) {
540 return bytecode >= Bytecode::kJumpIfNullConstant &&
541 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
544 // Returns true if the bytecode is a conditional jump taking
546 static constexpr bool IsConditionalJump(Bytecode bytecode) {
547 return bytecode >= Bytecode::kJumpIfNullConstant &&
548 bytecode <= Bytecode::kJumpIfNotHole;
551 bytecode is an unconditional jump.
552 static constexpr bool IsUnconditionalJump(Bytecode bytecode) {
553 return bytecode >= Bytecode::kJumpLoop &&
554 bytecode <= Bytecode::kJumpConstant;
557 // Returns true if the bytecode is a jump or a conditional jump taking
559 static constexpr bool IsJumpImmediate(Bytecode bytecode) {
560 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
561 IsConditionalJumpImmediate(bytecode);
564 // Returns true if the bytecode is a jump or conditional jump taking a
566 static constexpr bool IsJumpConstant(Bytecode bytecode) {
567 return bytecode >= Bytecode::kJumpConstant &&
568 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
571 // Returns true if the bytecode is a jump that internally coerces the
573 static constexpr bool IsJumpIfToBoolean(Bytecode bytecode) {
574 return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant &&
575 bytecode <= Bytecode::kJumpIfToBooleanFalse;
578 // Returns true if the bytecode is a jump or conditional jump taking
580 static constexpr bool IsJump(Bytecode bytecode) {
581 return bytecode >= Bytecode::kJumpLoop &&
582 bytecode <= Bytecode::kJumpIfNotHole;
585 // Returns true if the bytecode is a forward jump or conditional jump taking
587 static constexpr bool IsForwardJump(Bytecode bytecode) {
588 return bytecode >= Bytecode::kJump && bytecode <= Bytecode::kJumpIfNotHole;
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);
596 // Return true if |bytecode| is a jump without effects,
599 static constexpr bool IsJumpWithoutEffects(Bytecode bytecode) {
600 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
603 // Returns true if |bytecode| has no effects. These bytecodes only manipulate
605 static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) {
606 return (IsAccumulatorLoadWithoutEffects(bytecode) ||
607 IsRegisterLoadWithoutEffects(bytecode) ||
608 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
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;
616 // Returns true if |bytecode| puts a name in the accumulator.
617 static constexpr bool PutsNameInAccumulator(Bytecode bytecode) {
618 return bytecode == Bytecode::kTypeOf;
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;
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;
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;
646 // Returns the number of values which |bytecode| returns.
647 static constexpr size_t ReturnCount(Bytecode bytecode) {
648 return bytecode == Bytecode::kReturn ? 1 : 0;
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)];
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));
662 return GetOperandTypes(bytecode)[i];
667 static const OperandType* GetOperandTypes(Bytecode bytecode) {
668 DCHECK(bytecode <= Bytecode::kLast);
669 return kOperandTypes[static_cast<size_t>(bytecode)];
672 static bool OperandIsScalableSignedByte(Bytecode bytecode,
674 DCHECK(bytecode <= Bytecode::kLast);
675 return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
679 static bool OperandIsScalableUnsignedByte(Bytecode bytecode,
681 DCHECK(bytecode <= Bytecode::kLast);
682 return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
686 static bool OperandIsScalable(Bytecode bytecode, int operand_index) {
687 return OperandIsScalableSignedByte(bytecode, operand_index) ||
688 OperandIsScalableUnsignedByte(bytecode, operand_index);
691 // Returns true if the bytecode has wider operand forms.
692 static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
694 // Returns the size of the i-th operand of |bytecode|.
695 static OperandSize GetOperandSize(Bytecode bytecode, int i,
697 CHECK_LT(i, NumberOfOperands(bytecode));
698 return GetOperandSizes(bytecode, operand_scale)[i];
701 // Returns the operand sizes of |bytecode| with scale |operand_scale|.
702 static const OperandSize* GetOperandSizes(Bytecode bytecode,
704 DCHECK(bytecode <= Bytecode::kLast);
710 return kOperandSizes[static_cast<size_t>(bytecode)][scale_index];
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,
718 // Returns the size of the bytecode including its operands for the
720 static int Size(Bytecode bytecode, OperandScale operand_scale) {
721 DCHECK(bytecode <= Bytecode::kLast);
725 return kBytecodeSizes[static_cast<size_t>(bytecode)][scale_index];
728 // Returns a debug break bytecode to replace |bytecode|.
729 static Bytecode GetDebugBreak(Bytecode bytecode);
731 // Returns the equivalent jump bytecode without the accumulator coercion.
732 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
735 // through the bytecode's handler.
736 static bool MakesCallAlongCriticalPath(Bytecode bytecode);
738 // Returns true if the bytecode is a debug break.
739 static bool IsDebugBreak(Bytecode bytecode);
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);
786 // Returns true if a handler is generated for a bytecode at a given
790 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
837 const Bytecode& bytecode);