| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 | 69 |
| 70 Handle<BytecodeArray> output = | 70 Handle<BytecodeArray> output = |
| 71 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, | 71 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, |
| 72 parameter_count_, constant_pool); | 72 parameter_count_, constant_pool); |
| 73 bytecode_generated_ = true; | 73 bytecode_generated_ = true; |
| 74 return output; | 74 return output; |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 template <size_t N> | 78 template <size_t N> |
| 79 void BytecodeArrayBuilder::Output(uint8_t(&bytes)[N]) { | 79 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { |
| 80 DCHECK_EQ(Bytecodes::NumberOfOperands(Bytecodes::FromByte(bytes[0])), | 80 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), N); |
| 81 static_cast<int>(N) - 1); | |
| 82 last_bytecode_start_ = bytecodes()->size(); | 81 last_bytecode_start_ = bytecodes()->size(); |
| 83 for (int i = 1; i < static_cast<int>(N); i++) { | 82 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
| 84 DCHECK(OperandIsValid(Bytecodes::FromByte(bytes[0]), i - 1, bytes[i])); | 83 for (int i = 0; i < static_cast<int>(N); i++) { |
| 84 DCHECK(OperandIsValid(bytecode, i, operands[i])); |
| 85 switch (Bytecodes::GetOperandSize(bytecode, i)) { |
| 86 case OperandSize::kNone: |
| 87 UNREACHABLE(); |
| 88 case OperandSize::kByte: |
| 89 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); |
| 90 break; |
| 91 case OperandSize::kShort: { |
| 92 uint8_t operand_bytes[2]; |
| 93 Bytecodes::ShortOperandToBytes(operands[i], operand_bytes); |
| 94 bytecodes()->insert(bytecodes()->end(), operand_bytes, |
| 95 operand_bytes + 2); |
| 96 break; |
| 97 } |
| 98 } |
| 85 } | 99 } |
| 86 bytecodes()->insert(bytecodes()->end(), bytes, bytes + N); | |
| 87 } | 100 } |
| 88 | 101 |
| 89 | 102 |
| 90 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | 103 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 91 uint8_t operand1, uint8_t operand2) { | 104 uint32_t operand1, uint32_t operand2) { |
| 92 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0, operand1, operand2}; | 105 uint32_t operands[] = {operand0, operand1, operand2}; |
| 93 Output(bytes); | 106 Output(bytecode, operands); |
| 94 } | 107 } |
| 95 | 108 |
| 96 | 109 |
| 97 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | 110 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 98 uint8_t operand1) { | 111 uint32_t operand1) { |
| 99 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0, operand1}; | 112 uint32_t operands[] = {operand0, operand1}; |
| 100 Output(bytes); | 113 Output(bytecode, operands); |
| 101 } | 114 } |
| 102 | 115 |
| 103 | 116 |
| 104 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0) { | 117 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { |
| 105 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0}; | 118 uint32_t operands[] = {operand0}; |
| 106 Output(bytes); | 119 Output(bytecode, operands); |
| 107 } | 120 } |
| 108 | 121 |
| 109 | 122 |
| 110 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 123 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
| 111 uint8_t bytes[] = {Bytecodes::ToByte(bytecode)}; | 124 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
| 112 Output(bytes); | 125 last_bytecode_start_ = bytecodes()->size(); |
| 126 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
| 113 } | 127 } |
| 114 | 128 |
| 115 | 129 |
| 116 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 130 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
| 117 Register reg) { | 131 Register reg) { |
| 118 Output(BytecodeForBinaryOperation(op), reg.ToOperand()); | 132 Output(BytecodeForBinaryOperation(op), reg.ToOperand()); |
| 119 return *this; | 133 return *this; |
| 120 } | 134 } |
| 121 | 135 |
| 122 | 136 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 case Bytecode::kTestEqual: | 302 case Bytecode::kTestEqual: |
| 289 case Bytecode::kTestNotEqual: | 303 case Bytecode::kTestNotEqual: |
| 290 case Bytecode::kTestEqualStrict: | 304 case Bytecode::kTestEqualStrict: |
| 291 case Bytecode::kTestNotEqualStrict: | 305 case Bytecode::kTestNotEqualStrict: |
| 292 case Bytecode::kTestLessThan: | 306 case Bytecode::kTestLessThan: |
| 293 case Bytecode::kTestLessThanOrEqual: | 307 case Bytecode::kTestLessThanOrEqual: |
| 294 case Bytecode::kTestGreaterThan: | 308 case Bytecode::kTestGreaterThan: |
| 295 case Bytecode::kTestGreaterThanOrEqual: | 309 case Bytecode::kTestGreaterThanOrEqual: |
| 296 case Bytecode::kTestInstanceOf: | 310 case Bytecode::kTestInstanceOf: |
| 297 case Bytecode::kTestIn: | 311 case Bytecode::kTestIn: |
| 312 return *this; |
| 313 default: |
| 314 // Fall through to output kToBoolean. |
| 298 break; | 315 break; |
| 299 default: | |
| 300 Output(Bytecode::kToBoolean); | |
| 301 } | 316 } |
| 302 } | 317 } |
| 318 Output(Bytecode::kToBoolean); |
| 303 return *this; | 319 return *this; |
| 304 } | 320 } |
| 305 | 321 |
| 306 | 322 |
| 307 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { | 323 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { |
| 308 if (label->is_forward_target()) { | 324 if (label->is_forward_target()) { |
| 309 // 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. |
| 310 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); | 326 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); |
| 311 // 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. |
| 312 } | 328 } |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 } | 508 } |
| 493 | 509 |
| 494 | 510 |
| 495 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { | 511 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { |
| 496 DCHECK_EQ(reg_index, temporary_register_next_ - 1); | 512 DCHECK_EQ(reg_index, temporary_register_next_ - 1); |
| 497 temporary_register_next_ = reg_index; | 513 temporary_register_next_ = reg_index; |
| 498 } | 514 } |
| 499 | 515 |
| 500 | 516 |
| 501 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 517 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
| 502 uint8_t operand_value) const { | 518 uint32_t operand_value) const { |
| 503 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | 519 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); |
| 504 switch (operand_type) { | 520 switch (operand_type) { |
| 505 case OperandType::kNone: | 521 case OperandType::kNone: |
| 506 return false; | 522 return false; |
| 507 case OperandType::kCount: | 523 case OperandType::kIdx16: |
| 524 return static_cast<uint16_t>(operand_value) == operand_value; |
| 525 case OperandType::kCount8: |
| 508 case OperandType::kImm8: | 526 case OperandType::kImm8: |
| 509 case OperandType::kIdx: | 527 case OperandType::kIdx8: |
| 510 return true; | 528 return static_cast<uint8_t>(operand_value) == operand_value; |
| 511 case OperandType::kReg: { | 529 case OperandType::kReg8: { |
| 512 Register reg = Register::FromOperand(operand_value); | 530 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); |
| 513 if (reg.is_parameter()) { | 531 if (reg.is_parameter()) { |
| 514 int parameter_index = reg.ToParameterIndex(parameter_count_); | 532 int parameter_index = reg.ToParameterIndex(parameter_count_); |
| 515 return parameter_index >= 0 && parameter_index < parameter_count_; | 533 return parameter_index >= 0 && parameter_index < parameter_count_; |
| 516 } else { | 534 } else { |
| 517 return (reg.index() >= 0 && reg.index() < temporary_register_next_); | 535 return (reg.index() >= 0 && reg.index() < temporary_register_next_); |
| 518 } | 536 } |
| 519 } | 537 } |
| 520 } | 538 } |
| 521 UNREACHABLE(); | 539 UNREACHABLE(); |
| 522 return false; | 540 return false; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 | 627 |
| 610 Register TemporaryRegisterScope::NewRegister() { | 628 Register TemporaryRegisterScope::NewRegister() { |
| 611 count_++; | 629 count_++; |
| 612 last_register_index_ = builder_->BorrowTemporaryRegister(); | 630 last_register_index_ = builder_->BorrowTemporaryRegister(); |
| 613 return Register(last_register_index_); | 631 return Register(last_register_index_); |
| 614 } | 632 } |
| 615 | 633 |
| 616 } // namespace interpreter | 634 } // namespace interpreter |
| 617 } // namespace internal | 635 } // namespace internal |
| 618 } // namespace v8 | 636 } // namespace v8 |
| OLD | NEW |