Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/interpreter/bytecode-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
| 6 | 6 |
| 7 namespace v8 { | 7 namespace v8 { |
| 8 namespace internal { | 8 namespace internal { |
| 9 namespace interpreter { | 9 namespace interpreter { |
| 10 | 10 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 | 68 |
| 69 Handle<BytecodeArray> output = | 69 Handle<BytecodeArray> output = |
| 70 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, | 70 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, |
| 71 parameter_count_, constant_pool); | 71 parameter_count_, constant_pool); |
| 72 bytecode_generated_ = true; | 72 bytecode_generated_ = true; |
| 73 return output; | 73 return output; |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 template <size_t N> | 77 template <size_t N> |
| 78 void BytecodeArrayBuilder::Output(uint8_t(&bytes)[N]) { | 78 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { |
| 79 DCHECK_EQ(Bytecodes::NumberOfOperands(Bytecodes::FromByte(bytes[0])), | 79 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), N); |
| 80 static_cast<int>(N) - 1); | |
| 81 last_bytecode_start_ = bytecodes()->size(); | 80 last_bytecode_start_ = bytecodes()->size(); |
| 82 for (int i = 1; i < static_cast<int>(N); i++) { | 81 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
| 83 DCHECK(OperandIsValid(Bytecodes::FromByte(bytes[0]), i - 1, bytes[i])); | 82 for (int i = 0; i < static_cast<int>(N); i++) { |
| 83 DCHECK(OperandIsValid(bytecode, i, operands[i])); | |
| 84 switch (Bytecodes::SizeOfOperand(Bytecodes::GetOperandType(bytecode, i))) { | |
| 85 case OperandSize::kNone: | |
| 86 UNREACHABLE(); | |
| 87 case OperandSize::kByte: | |
| 88 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | |
| 89 break; | |
| 90 case OperandSize::kWide: { | |
| 91 uint8_t operand_bytes[2]; | |
| 92 Bytecodes::WideOperandToBytes(operands[i], operand_bytes); | |
| 93 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
| 94 operand_bytes + 2); | |
| 95 break; | |
| 96 } | |
| 97 } | |
| 84 } | 98 } |
| 85 bytecodes()->insert(bytecodes()->end(), bytes, bytes + N); | |
| 86 } | 99 } |
| 87 | 100 |
| 88 | 101 |
| 89 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | 102 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 90 uint8_t operand1, uint8_t operand2) { | 103 uint32_t operand1, uint32_t operand2) { |
| 91 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0, operand1, operand2}; | 104 uint32_t operands[] = {operand0, operand1, operand2}; |
| 92 Output(bytes); | 105 Output(bytecode, operands); |
| 93 } | 106 } |
| 94 | 107 |
| 95 | 108 |
| 96 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | 109 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 97 uint8_t operand1) { | 110 uint32_t operand1) { |
| 98 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0, operand1}; | 111 uint32_t operands[] = {operand0, operand1}; |
| 99 Output(bytes); | 112 Output(bytecode, operands); |
| 100 } | 113 } |
| 101 | 114 |
| 102 | 115 |
| 103 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0) { | 116 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { |
| 104 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0}; | 117 uint32_t operands[] = {operand0}; |
| 105 Output(bytes); | 118 Output(bytecode, operands); |
| 106 } | 119 } |
| 107 | 120 |
| 108 | 121 |
| 109 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 122 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
| 110 uint8_t bytes[] = {Bytecodes::ToByte(bytecode)}; | 123 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
| 111 Output(bytes); | 124 last_bytecode_start_ = bytecodes()->size(); |
| 125 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | |
| 112 } | 126 } |
| 113 | 127 |
| 114 | 128 |
| 115 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 129 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
| 116 Register reg) { | 130 Register reg) { |
| 117 Output(BytecodeForBinaryOperation(op), reg.ToOperand()); | 131 Output(BytecodeForBinaryOperation(op), reg.ToOperand()); |
| 118 return *this; | 132 return *this; |
| 119 } | 133 } |
| 120 | 134 |
| 121 | 135 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 case Bytecode::kTestEqual: | 301 case Bytecode::kTestEqual: |
| 288 case Bytecode::kTestNotEqual: | 302 case Bytecode::kTestNotEqual: |
| 289 case Bytecode::kTestEqualStrict: | 303 case Bytecode::kTestEqualStrict: |
| 290 case Bytecode::kTestNotEqualStrict: | 304 case Bytecode::kTestNotEqualStrict: |
| 291 case Bytecode::kTestLessThan: | 305 case Bytecode::kTestLessThan: |
| 292 case Bytecode::kTestLessThanEqual: | 306 case Bytecode::kTestLessThanEqual: |
| 293 case Bytecode::kTestGreaterThan: | 307 case Bytecode::kTestGreaterThan: |
| 294 case Bytecode::kTestGreaterThanEqual: | 308 case Bytecode::kTestGreaterThanEqual: |
| 295 case Bytecode::kTestInstanceOf: | 309 case Bytecode::kTestInstanceOf: |
| 296 case Bytecode::kTestIn: | 310 case Bytecode::kTestIn: |
| 311 return *this; | |
| 312 default: | |
| 313 // Fall through to output kToBoolean. | |
| 297 break; | 314 break; |
| 298 default: | |
| 299 Output(Bytecode::kToBoolean); | |
| 300 } | 315 } |
| 301 } | 316 } |
| 317 Output(Bytecode::kToBoolean); | |
| 318 | |
|
oth
2015/09/28 09:21:25
Nit - empty line.
rmcilroy
2015/10/01 14:09:14
Done.
| |
| 302 return *this; | 319 return *this; |
| 303 } | 320 } |
| 304 | 321 |
| 305 | 322 |
| 306 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { | 323 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { |
| 307 if (label->is_forward_target()) { | 324 if (label->is_forward_target()) { |
| 308 // An earlier jump instruction refers to this label. Update it's location. | 325 // An earlier jump instruction refers to this label. Update it's location. |
| 309 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); | 326 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); |
| 310 // Now treat as if the label will only be back referred to. | 327 // Now treat as if the label will only be back referred to. |
| 311 } | 328 } |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 } | 505 } |
| 489 | 506 |
| 490 | 507 |
| 491 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { | 508 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { |
| 492 DCHECK_EQ(reg_index, temporary_register_next_ - 1); | 509 DCHECK_EQ(reg_index, temporary_register_next_ - 1); |
| 493 temporary_register_next_ = reg_index; | 510 temporary_register_next_ = reg_index; |
| 494 } | 511 } |
| 495 | 512 |
| 496 | 513 |
| 497 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 514 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
| 498 uint8_t operand_value) const { | 515 uint32_t operand_value) const { |
| 499 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | 516 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); |
| 500 switch (operand_type) { | 517 switch (operand_type) { |
| 501 case OperandType::kNone: | 518 case OperandType::kNone: |
| 502 return false; | 519 return false; |
| 520 case OperandType::kWideIdx: | |
| 521 return static_cast<uint16_t>(operand_value) == operand_value; | |
| 503 case OperandType::kCount: | 522 case OperandType::kCount: |
| 504 case OperandType::kImm8: | 523 case OperandType::kImm8: |
| 505 case OperandType::kIdx: | 524 case OperandType::kIdx: |
| 506 return true; | 525 return static_cast<uint8_t>(operand_value) == operand_value; |
| 507 case OperandType::kReg: { | 526 case OperandType::kReg: { |
| 508 Register reg = Register::FromOperand(operand_value); | 527 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); |
| 509 if (reg.is_parameter()) { | 528 if (reg.is_parameter()) { |
| 510 int parameter_index = reg.ToParameterIndex(parameter_count_); | 529 int parameter_index = reg.ToParameterIndex(parameter_count_); |
| 511 return parameter_index >= 0 && parameter_index < parameter_count_; | 530 return parameter_index >= 0 && parameter_index < parameter_count_; |
| 512 } else { | 531 } else { |
| 513 return (reg.index() >= 0 && reg.index() < temporary_register_next_); | 532 return (reg.index() >= 0 && reg.index() < temporary_register_next_); |
| 514 } | 533 } |
| 515 } | 534 } |
| 516 } | 535 } |
| 517 UNREACHABLE(); | 536 UNREACHABLE(); |
| 518 return false; | 537 return false; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 | 624 |
| 606 Register TemporaryRegisterScope::NewRegister() { | 625 Register TemporaryRegisterScope::NewRegister() { |
| 607 count_++; | 626 count_++; |
| 608 last_register_index_ = builder_->BorrowTemporaryRegister(); | 627 last_register_index_ = builder_->BorrowTemporaryRegister(); |
| 609 return Register(last_register_index_); | 628 return Register(last_register_index_); |
| 610 } | 629 } |
| 611 | 630 |
| 612 } // namespace interpreter | 631 } // namespace interpreter |
| 613 } // namespace internal | 632 } // namespace internal |
| 614 } // namespace v8 | 633 } // namespace v8 |
| OLD | NEW |