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 |