Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/interpreter/bytecode-array-builder.h" | |
| 6 | |
| 7 namespace v8 { | |
| 8 namespace internal { | |
| 9 namespace interpreter { | |
| 10 | |
| 11 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate) | |
| 12 : isolate_(isolate), | |
| 13 bytecode_generated_(false), | |
| 14 local_register_count_(-1), | |
| 15 temporary_register_next_(-1) {} | |
| 16 | |
| 17 | |
| 18 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { | |
| 19 local_register_count_ = number_of_locals; | |
| 20 temporary_register_next_ = local_register_count_; | |
| 21 } | |
| 22 | |
| 23 | |
| 24 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | |
| 25 DCHECK(!bytecode_generated_); | |
| 26 DCHECK(local_register_count_ >= 0); | |
| 27 int bytecode_size = static_cast<int>(bytecodes_.size()); | |
| 28 int register_count = local_register_count_ + temporary_register_count_; | |
| 29 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.
| |
| 30 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( | |
| 31 bytecode_size, &bytecodes_.front(), frame_size); | |
| 32 bytecode_generated_ = true; | |
| 33 return output; | |
| 34 } | |
| 35 | |
| 36 | |
| 37 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value binop, | |
| 38 int reg) { | |
| 39 Output(BytecodeForBinaryOperation(binop), reg); | |
| 40 return *this; | |
| 41 } | |
| 42 | |
| 43 | |
| 44 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | |
| 45 v8::internal::Smi* smi) { | |
| 46 int32_t raw_smi = smi->value(); | |
| 47 if (raw_smi == 0) { | |
| 48 Output(Bytecode::kLdaZero); | |
| 49 } else if (raw_smi > -128 && raw_smi <= 128) { | |
| 50 Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi)); | |
| 51 } else { | |
| 52 // TODO(oth): Put Smi in constant pool. | |
| 53 UNIMPLEMENTED(); | |
| 54 } | |
| 55 return *this; | |
| 56 } | |
| 57 | |
| 58 | |
| 59 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { | |
| 60 Output(Bytecode::kLdaUndefined); | |
| 61 return *this; | |
| 62 } | |
| 63 | |
| 64 | |
| 65 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { | |
| 66 Output(Bytecode::kLdaNull); | |
| 67 return *this; | |
| 68 } | |
| 69 | |
| 70 | |
| 71 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() { | |
| 72 Output(Bytecode::kLdaTheHole); | |
| 73 return *this; | |
| 74 } | |
| 75 | |
| 76 | |
| 77 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() { | |
| 78 Output(Bytecode::kLdaTrue); | |
| 79 return *this; | |
| 80 } | |
| 81 | |
| 82 | |
| 83 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { | |
| 84 Output(Bytecode::kLdaFalse); | |
| 85 return *this; | |
| 86 } | |
| 87 | |
| 88 | |
| 89 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | |
| 90 int reg) { | |
| 91 Output(Bytecode::kLdar, reg); | |
| 92 return *this; | |
| 93 } | |
| 94 | |
| 95 | |
| 96 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | |
| 97 int reg) { | |
| 98 Output(Bytecode::kStar, reg); | |
| 99 return *this; | |
| 100 } | |
| 101 | |
| 102 | |
| 103 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { | |
| 104 Output(Bytecode::kReturn); | |
| 105 return *this; | |
| 106 } | |
| 107 | |
| 108 | |
| 109 int BytecodeArrayBuilder::AllocateTemporaryRegister() { | |
| 110 DCHECK(local_register_count_ >= 0); | |
| 111 int temporary_register = temporary_register_next_++; | |
| 112 int count = temporary_register_next_ - local_register_count_; | |
| 113 if (count > temporary_register_count_) { | |
| 114 temporary_register_count_ = count; | |
| 115 } | |
| 116 return temporary_register; | |
| 117 } | |
| 118 | |
| 119 | |
| 120 void BytecodeArrayBuilder::FreeTemporaryRegister(int reg) { | |
| 121 DCHECK(reg == temporary_register_next_ - 1); | |
| 122 temporary_register_next_ = reg; | |
| 123 } | |
| 124 | |
| 125 | |
| 126 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
| 127 uint8_t operand1, uint8_t operand2) { | |
| 128 CHECK(Bytecodes::NumberOfOperands(bytecode) == 3); | |
| 129 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
| 130 bytecodes_.push_back(operand0); | |
| 131 bytecodes_.push_back(operand1); | |
| 132 bytecodes_.push_back(operand2); | |
| 133 } | |
| 134 | |
| 135 | |
| 136 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
| 137 uint8_t operand1) { | |
| 138 CHECK(Bytecodes::NumberOfOperands(bytecode) == 2); | |
| 139 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
| 140 bytecodes_.push_back(operand0); | |
| 141 bytecodes_.push_back(operand1); | |
| 142 } | |
| 143 | |
| 144 | |
| 145 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0) { | |
| 146 CHECK(Bytecodes::NumberOfOperands(bytecode) == 1); | |
| 147 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
| 148 bytecodes_.push_back(operand0); | |
| 149 } | |
| 150 | |
| 151 | |
| 152 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | |
| 153 CHECK(Bytecodes::NumberOfOperands(bytecode) == 0); | |
| 154 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
| 155 } | |
| 156 | |
| 157 | |
| 158 // static | |
| 159 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | |
| 160 switch (op) { | |
| 161 case Token::Value::ADD: | |
| 162 return Bytecode::kAdd; | |
| 163 case Token::Value::SUB: | |
| 164 return Bytecode::kSub; | |
| 165 case Token::Value::MUL: | |
| 166 return Bytecode::kMul; | |
| 167 case Token::Value::DIV: | |
| 168 return Bytecode::kDiv; | |
| 169 default: | |
| 170 UNIMPLEMENTED(); | |
| 171 return static_cast<Bytecode>(-1); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 } // namespace interpreter | |
| 176 } // namespace internal | |
| 177 } // namespace v8 | |
| OLD | NEW |