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 |