Index: src/interpreter/bytecode-array-builder.cc |
diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4cc5baefff538d906e648fb93dcef069aaf4094b |
--- /dev/null |
+++ b/src/interpreter/bytecode-array-builder.cc |
@@ -0,0 +1,177 @@ |
+// Copyright 2015 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "src/interpreter/bytecode-array-builder.h" |
+ |
+namespace v8 { |
+namespace internal { |
+namespace interpreter { |
+ |
+BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate) |
+ : isolate_(isolate), |
+ bytecode_generated_(false), |
+ local_register_count_(-1), |
+ temporary_register_next_(-1) {} |
+ |
+ |
+void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { |
+ local_register_count_ = number_of_locals; |
+ temporary_register_next_ = local_register_count_; |
+} |
+ |
+ |
+Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
+ DCHECK(!bytecode_generated_); |
+ DCHECK(local_register_count_ >= 0); |
+ int bytecode_size = static_cast<int>(bytecodes_.size()); |
+ int register_count = local_register_count_ + temporary_register_count_; |
+ int frame_size = register_count * sizeof(intptr_t); |
rmcilroy
2015/07/31 09:56:19
replace sizeof(intptr_t) with kPointerSize (otherw
oth
2015/07/31 11:20:59
Done.
|
+ Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( |
+ bytecode_size, &bytecodes_.front(), frame_size); |
+ bytecode_generated_ = true; |
+ return output; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value binop, |
+ int reg) { |
+ Output(BytecodeForBinaryOperation(binop), reg); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
+ v8::internal::Smi* smi) { |
+ int32_t raw_smi = smi->value(); |
+ if (raw_smi == 0) { |
+ Output(Bytecode::kLdaZero); |
+ } else if (raw_smi > -128 && raw_smi <= 128) { |
+ Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi)); |
+ } else { |
+ // TODO(oth): Put Smi in constant pool. |
+ UNIMPLEMENTED(); |
+ } |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { |
+ Output(Bytecode::kLdaUndefined); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { |
+ Output(Bytecode::kLdaNull); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() { |
+ Output(Bytecode::kLdaTheHole); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() { |
+ Output(Bytecode::kLdaTrue); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { |
+ Output(Bytecode::kLdaFalse); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
+ int reg) { |
+ Output(Bytecode::kLdar, reg); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
+ int reg) { |
+ Output(Bytecode::kStar, reg); |
+ return *this; |
+} |
+ |
+ |
+BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { |
+ Output(Bytecode::kReturn); |
+ return *this; |
+} |
+ |
+ |
+int BytecodeArrayBuilder::AllocateTemporaryRegister() { |
+ DCHECK(local_register_count_ >= 0); |
+ int temporary_register = temporary_register_next_++; |
+ int count = temporary_register_next_ - local_register_count_; |
+ if (count > temporary_register_count_) { |
+ temporary_register_count_ = count; |
+ } |
+ return temporary_register; |
+} |
+ |
+ |
+void BytecodeArrayBuilder::FreeTemporaryRegister(int reg) { |
+ DCHECK(reg == temporary_register_next_ - 1); |
+ temporary_register_next_ = reg; |
+} |
+ |
+ |
+void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, |
+ uint8_t operand1, uint8_t operand2) { |
+ CHECK(Bytecodes::NumberOfOperands(bytecode) == 3); |
+ bytecodes_.push_back(Bytecodes::ToByte(bytecode)); |
+ bytecodes_.push_back(operand0); |
+ bytecodes_.push_back(operand1); |
+ bytecodes_.push_back(operand2); |
+} |
+ |
+ |
+void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, |
+ uint8_t operand1) { |
+ CHECK(Bytecodes::NumberOfOperands(bytecode) == 2); |
+ bytecodes_.push_back(Bytecodes::ToByte(bytecode)); |
+ bytecodes_.push_back(operand0); |
+ bytecodes_.push_back(operand1); |
+} |
+ |
+ |
+void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0) { |
+ CHECK(Bytecodes::NumberOfOperands(bytecode) == 1); |
+ bytecodes_.push_back(Bytecodes::ToByte(bytecode)); |
+ bytecodes_.push_back(operand0); |
+} |
+ |
+ |
+void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
+ CHECK(Bytecodes::NumberOfOperands(bytecode) == 0); |
+ bytecodes_.push_back(Bytecodes::ToByte(bytecode)); |
+} |
+ |
+ |
+// static |
+Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
+ switch (op) { |
+ case Token::Value::ADD: |
+ return Bytecode::kAdd; |
+ case Token::Value::SUB: |
+ return Bytecode::kSub; |
+ case Token::Value::MUL: |
+ return Bytecode::kMul; |
+ case Token::Value::DIV: |
+ return Bytecode::kDiv; |
+ default: |
+ UNIMPLEMENTED(); |
+ return static_cast<Bytecode>(-1); |
+ } |
+} |
+ |
+} // namespace interpreter |
+} // namespace internal |
+} // namespace v8 |