| Index: src/interpreter/bytecode-array-builder.h
|
| diff --git a/src/interpreter/bytecode-array-builder.h b/src/interpreter/bytecode-array-builder.h
|
| index f7a8dddebd3f77d78cc90ce58264ad3736b3be4e..c2ea190cfe9897dc0ed76569ed4eb22cdae0850e 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 {
|
| @@ -74,27 +75,55 @@ 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();
|
|
|
| private:
|
| static Bytecode BytecodeForBinaryOperation(Token::Value op);
|
| - static bool FitsInByteOperand(int value);
|
| - static bool FitsInByteOperand(size_t value);
|
| -
|
| - 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 BytecodeForCompareOperation(Token::Value op);
|
| + static bool FitsInIdxOperand(int value);
|
| + static bool FitsInIdxOperand(size_t value);
|
| + static bool FitsInImm8Operand(int value);
|
| + static bool IsJumpWithSmi8Operand(Bytecode jump_bytecode);
|
| + static Bytecode GetJumpWithConstantOperand(Bytecode jump_with_smi8_operand);
|
| +
|
| + ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
|
| + const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; }
|
| + Isolate* isolate() const { return isolate_; }
|
| +
|
| + template <size_t N>
|
| + 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);
|
| + void OutputJump(Bytecode jump_bytecode,
|
| + const ZoneVector<uint8_t>::iterator& jump_target);
|
| + BytecodeArrayBuilder& Jump(Bytecode jump_bytecode, BytecodeLabel* label);
|
|
|
| bool OperandIsValid(Bytecode bytecode, int operand_index,
|
| uint8_t operand_value) const;
|
|
|
| size_t GetConstantPoolEntry(Handle<Object> object);
|
|
|
| + // Scope helpers used by TemporaryRegisterScope
|
| int BorrowTemporaryRegister();
|
| void ReturnTemporaryRegister(int reg_index);
|
|
|
| @@ -114,6 +143,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 {
|
|
|