| Index: src/interpreter/bytecodes.h
|
| diff --git a/src/interpreter/bytecodes.h b/src/interpreter/bytecodes.h
|
| index 43aeb30d3bb500ce3ed5dff2ad033aeb568fb0bb..36041cb97e5bc59b27a5be846787275ef2844395 100644
|
| --- a/src/interpreter/bytecodes.h
|
| +++ b/src/interpreter/bytecodes.h
|
| @@ -5,13 +5,12 @@
|
| #ifndef V8_INTERPRETER_BYTECODES_H_
|
| #define V8_INTERPRETER_BYTECODES_H_
|
|
|
| -#include <cstdint>
|
| #include <iosfwd>
|
| -#include <string>
|
| -
|
| -// This interface and it's implementation are independent of the
|
| -// libv8_base library as they are used by the interpreter and the
|
| -// standalone mkpeephole table generator program.
|
| +
|
| +// Clients of this interface shouldn't depend on lots of interpreter internals.
|
| +// Do not include anything from src/interpreter here!
|
| +#include "src/frames.h"
|
| +#include "src/utils.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -287,12 +286,12 @@
|
| kReadWrite = kRead | kWrite
|
| };
|
|
|
| -inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
|
| +V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
|
| int result = static_cast<int>(lhs) & static_cast<int>(rhs);
|
| return static_cast<AccumulatorUse>(result);
|
| }
|
|
|
| -inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
|
| +V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
|
| int result = static_cast<int>(lhs) | static_cast<int>(rhs);
|
| return static_cast<AccumulatorUse>(result);
|
| }
|
| @@ -349,6 +348,7 @@
|
| #undef COUNT_OPERAND_TYPES
|
| };
|
|
|
| +
|
| // Enumeration of interpreter bytecodes.
|
| enum class Bytecode : uint8_t {
|
| #define DECLARE_BYTECODE(Name, ...) k##Name,
|
| @@ -361,7 +361,94 @@
|
| #undef COUNT_BYTECODE
|
| };
|
|
|
| -class Bytecodes final {
|
| +
|
| +// An interpreter Register which is located in the function's Register file
|
| +// in its stack-frame. Register hold parameters, this, and expression values.
|
| +class Register final {
|
| + public:
|
| + explicit Register(int index = kInvalidIndex) : index_(index) {}
|
| +
|
| + int index() const { return index_; }
|
| + bool is_parameter() const { return index() < 0; }
|
| + bool is_valid() const { return index_ != kInvalidIndex; }
|
| +
|
| + static Register FromParameterIndex(int index, int parameter_count);
|
| + int ToParameterIndex(int parameter_count) const;
|
| +
|
| + // Returns an invalid register.
|
| + static Register invalid_value() { return Register(); }
|
| +
|
| + // Returns the register for the function's closure object.
|
| + static Register function_closure();
|
| + bool is_function_closure() const;
|
| +
|
| + // Returns the register which holds the current context object.
|
| + static Register current_context();
|
| + bool is_current_context() const;
|
| +
|
| + // Returns the register for the incoming new target value.
|
| + static Register new_target();
|
| + bool is_new_target() const;
|
| +
|
| + // Returns the register for the bytecode array.
|
| + static Register bytecode_array();
|
| + bool is_bytecode_array() const;
|
| +
|
| + // Returns the register for the saved bytecode offset.
|
| + static Register bytecode_offset();
|
| + bool is_bytecode_offset() const;
|
| +
|
| + // Returns a register that can be used to represent the accumulator
|
| + // within code in the interpreter, but should never be emitted in
|
| + // bytecode.
|
| + static Register virtual_accumulator();
|
| +
|
| + OperandSize SizeOfOperand() const;
|
| +
|
| + int32_t ToOperand() const { return kRegisterFileStartOffset - index_; }
|
| + static Register FromOperand(int32_t operand) {
|
| + return Register(kRegisterFileStartOffset - operand);
|
| + }
|
| +
|
| + static bool AreContiguous(Register reg1, Register reg2,
|
| + Register reg3 = Register(),
|
| + Register reg4 = Register(),
|
| + Register reg5 = Register());
|
| +
|
| + std::string ToString(int parameter_count);
|
| +
|
| + bool operator==(const Register& other) const {
|
| + return index() == other.index();
|
| + }
|
| + bool operator!=(const Register& other) const {
|
| + return index() != other.index();
|
| + }
|
| + bool operator<(const Register& other) const {
|
| + return index() < other.index();
|
| + }
|
| + bool operator<=(const Register& other) const {
|
| + return index() <= other.index();
|
| + }
|
| + bool operator>(const Register& other) const {
|
| + return index() > other.index();
|
| + }
|
| + bool operator>=(const Register& other) const {
|
| + return index() >= other.index();
|
| + }
|
| +
|
| + private:
|
| + static const int kInvalidIndex = kMaxInt;
|
| + static const int kRegisterFileStartOffset =
|
| + InterpreterFrameConstants::kRegisterFileFromFp / kPointerSize;
|
| +
|
| + void* operator new(size_t size);
|
| + void operator delete(void* p);
|
| +
|
| + int index_;
|
| +};
|
| +
|
| +
|
| +class Bytecodes {
|
| public:
|
| // The maximum number of operands a bytecode may have.
|
| static const int kMaxOperands = 4;
|
| @@ -385,7 +472,10 @@
|
| static const char* OperandSizeToString(OperandSize operand_size);
|
|
|
| // Returns byte value of bytecode.
|
| - static uint8_t ToByte(Bytecode bytecode);
|
| + static uint8_t ToByte(Bytecode bytecode) {
|
| + DCHECK_LE(bytecode, Bytecode::kLast);
|
| + return static_cast<uint8_t>(bytecode);
|
| + }
|
|
|
| // Returns bytecode for |value|.
|
| static Bytecode FromByte(uint8_t value);
|
| @@ -545,6 +635,25 @@
|
|
|
| // Returns true if |operand_type| is unsigned, false if signed.
|
| static bool IsUnsignedOperandType(OperandType operand_type);
|
| +
|
| + // Decodes a register operand in a byte array.
|
| + static Register DecodeRegisterOperand(const uint8_t* operand_start,
|
| + OperandType operand_type,
|
| + OperandScale operand_scale);
|
| +
|
| + // Decodes a signed operand in a byte array.
|
| + static int32_t DecodeSignedOperand(const uint8_t* operand_start,
|
| + OperandType operand_type,
|
| + OperandScale operand_scale);
|
| +
|
| + // Decodes an unsigned operand in a byte array.
|
| + static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
|
| + OperandType operand_type,
|
| + OperandScale operand_scale);
|
| +
|
| + // Decode a single bytecode and operands to |os|.
|
| + static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
|
| + int number_of_parameters);
|
|
|
| // Returns true if a handler is generated for a bytecode at a given
|
| // operand scale. All bytecodes have handlers at OperandScale::kSingle,
|
| @@ -557,6 +666,33 @@
|
|
|
| // Return the operand size required to hold an unsigned operand.
|
| static OperandSize SizeForUnsignedOperand(uint32_t value);
|
| +
|
| + private:
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes);
|
| +};
|
| +
|
| +class CreateObjectLiteralFlags {
|
| + public:
|
| + class FlagsBits : public BitField8<int, 0, 3> {};
|
| + class FastClonePropertiesCountBits
|
| + : public BitField8<int, FlagsBits::kNext, 3> {};
|
| +
|
| + static uint8_t Encode(bool fast_clone_supported, int properties_count,
|
| + int runtime_flags);
|
| +
|
| + private:
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(CreateObjectLiteralFlags);
|
| +};
|
| +
|
| +class CreateClosureFlags {
|
| + public:
|
| + class PretenuredBit : public BitField8<bool, 0, 1> {};
|
| + class FastNewClosureBit : public BitField8<bool, PretenuredBit::kNext, 1> {};
|
| +
|
| + static uint8_t Encode(bool pretenure, bool is_function_scope);
|
| +
|
| + private:
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(CreateClosureFlags);
|
| };
|
|
|
| std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode);
|
|
|