| Index: src/interpreter/bytecode-array-builder.h
|
| diff --git a/src/interpreter/bytecode-array-builder.h b/src/interpreter/bytecode-array-builder.h
|
| index d1277a4ff01d1ce13f146ef65ac096bc15f86136..d68d5e7ffbf4b3860cfa985eb1d041732a799a8e 100644
|
| --- a/src/interpreter/bytecode-array-builder.h
|
| +++ b/src/interpreter/bytecode-array-builder.h
|
| @@ -20,6 +20,7 @@ class Isolate;
|
|
|
| namespace interpreter {
|
|
|
| +class BytecodeLabel;
|
| class Register;
|
|
|
| class BytecodeArrayBuilder {
|
| @@ -35,9 +36,6 @@ class BytecodeArrayBuilder {
|
| void set_locals_count(int number_of_locals);
|
| int locals_count() const;
|
|
|
| - // Returns true if the bytecode has an explicit return at the end.
|
| - bool HasExplicitReturn();
|
| -
|
| Register Parameter(int parameter_index);
|
|
|
| // Constant loads to accumulator.
|
| @@ -77,33 +75,69 @@ class BytecodeArrayBuilder {
|
| BytecodeArrayBuilder& Call(Register callable, Register receiver,
|
| size_t arg_count);
|
|
|
| - // Operators.
|
| + // Operators (register == lhs, accumulator = rhs).
|
| BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg);
|
|
|
| + // Tests.
|
| + BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg,
|
| + LanguageMode language_mode);
|
| +
|
| + // Casts
|
| + BytecodeArrayBuilder& CastAccumulatorToBoolean();
|
| +
|
| // Flow Control.
|
| + BytecodeArrayBuilder& Bind(BytecodeLabel* label);
|
| + BytecodeArrayBuilder& Jump(BytecodeLabel* label);
|
| + BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label);
|
| + BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label);
|
| BytecodeArrayBuilder& Return();
|
|
|
| + BytecodeArrayBuilder& EnterBlock();
|
| + BytecodeArrayBuilder& LeaveBlock();
|
| +
|
| private:
|
| - static Bytecode BytecodeForBinaryOperation(Token::Value op);
|
| - static bool FitsInByteOperand(int value);
|
| - static bool FitsInByteOperand(size_t value);
|
| + ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
|
| + const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; }
|
| + Isolate* isolate() const { return isolate_; }
|
|
|
| - void Output(Bytecode bytecode, uint8_t r0, uint8_t r1, uint8_t r2);
|
| - void Output(Bytecode bytecode, uint8_t r0, uint8_t r1);
|
| - void Output(Bytecode bytecode, uint8_t r0);
|
| + static Bytecode BytecodeForBinaryOperation(Token::Value op);
|
| + static Bytecode BytecodeForCompareOperation(Token::Value op);
|
| + static bool FitsInIdxOperand(int value);
|
| + static bool FitsInIdxOperand(size_t value);
|
| + static bool FitsInImm8Operand(int value);
|
| + static bool IsJumpWithImm8Operand(Bytecode jump_bytecode);
|
| + static Bytecode GetJumpWithConstantOperand(Bytecode jump_with_smi8_operand);
|
| +
|
| + template <size_t N>
|
| + INLINE(void Output(uint8_t(&bytes)[N]));
|
| + void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1,
|
| + uint8_t operand2);
|
| + void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1);
|
| + void Output(Bytecode bytecode, uint8_t operand0);
|
| void Output(Bytecode bytecode);
|
| + void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target,
|
| + ZoneVector<uint8_t>::iterator jump_location);
|
| + BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode,
|
| + BytecodeLabel* label);
|
| +
|
| + void EnsureReturn();
|
|
|
| bool OperandIsValid(Bytecode bytecode, int operand_index,
|
| uint8_t operand_value) const;
|
| + bool LastBytecodeInSameBlock() const;
|
|
|
| size_t GetConstantPoolEntry(Handle<Object> object);
|
|
|
| + // Scope helpers used by TemporaryRegisterScope
|
| int BorrowTemporaryRegister();
|
| void ReturnTemporaryRegister(int reg_index);
|
|
|
| Isolate* isolate_;
|
| ZoneVector<uint8_t> bytecodes_;
|
| bool bytecode_generated_;
|
| + size_t last_block_end_;
|
| + size_t last_bytecode_start_;
|
| + bool return_seen_in_block_;
|
|
|
| IdentityMap<size_t> constants_map_;
|
| ZoneVector<Handle<Object>> constants_;
|
| @@ -117,6 +151,47 @@ class BytecodeArrayBuilder {
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArrayBuilder);
|
| };
|
|
|
| +
|
| +// A label representing a branch target in a bytecode array. When a
|
| +// label is bound, it represents a known position in the bytecode
|
| +// array. For labels that are forward references there can be at most
|
| +// one reference whilst it is unbound.
|
| +class BytecodeLabel final {
|
| + public:
|
| + BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {}
|
| + ~BytecodeLabel() { DCHECK(bound_ && offset_ != kInvalidOffset); }
|
| +
|
| + private:
|
| + static const size_t kInvalidOffset = static_cast<size_t>(-1);
|
| +
|
| + INLINE(void bind_to(size_t offset)) {
|
| + DCHECK(!bound_ && offset != kInvalidOffset);
|
| + offset_ = offset;
|
| + bound_ = true;
|
| + }
|
| + INLINE(void set_referrer(size_t offset)) {
|
| + DCHECK(!bound_ && offset != kInvalidOffset);
|
| + offset_ = offset;
|
| + }
|
| + INLINE(size_t offset() const) { return offset_; }
|
| + INLINE(bool is_bound() const) { return bound_; }
|
| + INLINE(bool is_forward_target() const) {
|
| + return offset() != kInvalidOffset && !is_bound();
|
| + }
|
| +
|
| + // There are three states for a label:
|
| + // bound_ offset_
|
| + // UNSET false kInvalidOffset
|
| + // FORWARD_TARGET false Offset of referring jump
|
| + // BACKWARD_TARGET true Offset of label in bytecode array when bound
|
| + bool bound_;
|
| + size_t offset_;
|
| +
|
| + friend class BytecodeArrayBuilder;
|
| + DISALLOW_COPY_AND_ASSIGN(BytecodeLabel);
|
| +};
|
| +
|
| +
|
| // A stack-allocated class than allows the instantiator to allocate
|
| // temporary registers that are cleaned up when scope is closed.
|
| class TemporaryRegisterScope {
|
|
|