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::GetOperandSize(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::kShort: { |
| 91 uint8_t operand_bytes[2]; |
| 92 Bytecodes::ShortOperandToBytes(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); |
302 return *this; | 318 return *this; |
303 } | 319 } |
304 | 320 |
305 | 321 |
306 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { | 322 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { |
307 if (label->is_forward_target()) { | 323 if (label->is_forward_target()) { |
308 // An earlier jump instruction refers to this label. Update it's location. | 324 // An earlier jump instruction refers to this label. Update it's location. |
309 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); | 325 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); |
310 // Now treat as if the label will only be back referred to. | 326 // Now treat as if the label will only be back referred to. |
311 } | 327 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 } | 504 } |
489 | 505 |
490 | 506 |
491 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { | 507 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { |
492 DCHECK_EQ(reg_index, temporary_register_next_ - 1); | 508 DCHECK_EQ(reg_index, temporary_register_next_ - 1); |
493 temporary_register_next_ = reg_index; | 509 temporary_register_next_ = reg_index; |
494 } | 510 } |
495 | 511 |
496 | 512 |
497 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 513 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
498 uint8_t operand_value) const { | 514 uint32_t operand_value) const { |
499 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | 515 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); |
500 switch (operand_type) { | 516 switch (operand_type) { |
501 case OperandType::kNone: | 517 case OperandType::kNone: |
502 return false; | 518 return false; |
503 case OperandType::kCount: | 519 case OperandType::kIdx16: |
| 520 return static_cast<uint16_t>(operand_value) == operand_value; |
| 521 case OperandType::kCount8: |
504 case OperandType::kImm8: | 522 case OperandType::kImm8: |
505 case OperandType::kIdx: | 523 case OperandType::kIdx8: |
506 return true; | 524 return static_cast<uint8_t>(operand_value) == operand_value; |
507 case OperandType::kReg: { | 525 case OperandType::kReg8: { |
508 Register reg = Register::FromOperand(operand_value); | 526 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); |
509 if (reg.is_parameter()) { | 527 if (reg.is_parameter()) { |
510 int parameter_index = reg.ToParameterIndex(parameter_count_); | 528 int parameter_index = reg.ToParameterIndex(parameter_count_); |
511 return parameter_index >= 0 && parameter_index < parameter_count_; | 529 return parameter_index >= 0 && parameter_index < parameter_count_; |
512 } else { | 530 } else { |
513 return (reg.index() >= 0 && reg.index() < temporary_register_next_); | 531 return (reg.index() >= 0 && reg.index() < temporary_register_next_); |
514 } | 532 } |
515 } | 533 } |
516 } | 534 } |
517 UNREACHABLE(); | 535 UNREACHABLE(); |
518 return false; | 536 return false; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 | 623 |
606 Register TemporaryRegisterScope::NewRegister() { | 624 Register TemporaryRegisterScope::NewRegister() { |
607 count_++; | 625 count_++; |
608 last_register_index_ = builder_->BorrowTemporaryRegister(); | 626 last_register_index_ = builder_->BorrowTemporaryRegister(); |
609 return Register(last_register_index_); | 627 return Register(last_register_index_); |
610 } | 628 } |
611 | 629 |
612 } // namespace interpreter | 630 } // namespace interpreter |
613 } // namespace internal | 631 } // namespace internal |
614 } // namespace v8 | 632 } // namespace v8 |
OLD | NEW |