| 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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 return *this; | 473 return *this; |
| 474 } | 474 } |
| 475 | 475 |
| 476 | 476 |
| 477 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { | 477 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
| 478 Output(Bytecode::kPopContext, context.ToOperand()); | 478 Output(Bytecode::kPopContext, context.ToOperand()); |
| 479 return *this; | 479 return *this; |
| 480 } | 480 } |
| 481 | 481 |
| 482 | 482 |
| 483 bool BytecodeArrayBuilder::NeedToBooleanCast() { |
| 484 if (!LastBytecodeInSameBlock()) { |
| 485 // If the previous bytecode was from a different block return false. |
| 486 return true; |
| 487 } |
| 488 |
| 489 // If the previous bytecode puts a boolean in the accumulator return true. |
| 490 switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) { |
| 491 case Bytecode::kToBoolean: |
| 492 UNREACHABLE(); |
| 493 case Bytecode::kLdaTrue: |
| 494 case Bytecode::kLdaFalse: |
| 495 case Bytecode::kLogicalNot: |
| 496 case Bytecode::kTestEqual: |
| 497 case Bytecode::kTestNotEqual: |
| 498 case Bytecode::kTestEqualStrict: |
| 499 case Bytecode::kTestNotEqualStrict: |
| 500 case Bytecode::kTestLessThan: |
| 501 case Bytecode::kTestLessThanOrEqual: |
| 502 case Bytecode::kTestGreaterThan: |
| 503 case Bytecode::kTestGreaterThanOrEqual: |
| 504 case Bytecode::kTestInstanceOf: |
| 505 case Bytecode::kTestIn: |
| 506 case Bytecode::kForInDone: |
| 507 return false; |
| 508 default: |
| 509 return true; |
| 510 } |
| 511 } |
| 512 |
| 513 |
| 483 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { | 514 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { |
| 484 if (LastBytecodeInSameBlock()) { | 515 // If the previous bytecode puts a boolean in the accumulator |
| 485 // If the previous bytecode puts a boolean in the accumulator | 516 // there is no need to emit an instruction. |
| 486 // there is no need to emit an instruction. | 517 if (NeedToBooleanCast()) { |
| 487 switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) { | 518 Output(Bytecode::kToBoolean); |
| 488 case Bytecode::kToBoolean: | |
| 489 UNREACHABLE(); | |
| 490 case Bytecode::kLdaTrue: | |
| 491 case Bytecode::kLdaFalse: | |
| 492 case Bytecode::kLogicalNot: | |
| 493 case Bytecode::kTestEqual: | |
| 494 case Bytecode::kTestNotEqual: | |
| 495 case Bytecode::kTestEqualStrict: | |
| 496 case Bytecode::kTestNotEqualStrict: | |
| 497 case Bytecode::kTestLessThan: | |
| 498 case Bytecode::kTestLessThanOrEqual: | |
| 499 case Bytecode::kTestGreaterThan: | |
| 500 case Bytecode::kTestGreaterThanOrEqual: | |
| 501 case Bytecode::kTestInstanceOf: | |
| 502 case Bytecode::kTestIn: | |
| 503 return *this; | |
| 504 default: | |
| 505 // Fall through to output kToBoolean. | |
| 506 break; | |
| 507 } | |
| 508 } | 519 } |
| 509 Output(Bytecode::kToBoolean); | |
| 510 return *this; | 520 return *this; |
| 511 } | 521 } |
| 512 | 522 |
| 513 | 523 |
| 514 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { | 524 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { |
| 515 Output(Bytecode::kToObject); | 525 Output(Bytecode::kToObject); |
| 516 return *this; | 526 return *this; |
| 517 } | 527 } |
| 518 | 528 |
| 519 | 529 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 // to match the size of the code it's replacing. In future, | 616 // to match the size of the code it's replacing. In future, |
| 607 // there will probably be a jump with 32-bit operand for cases | 617 // there will probably be a jump with 32-bit operand for cases |
| 608 // when constant pool is full, but that needs to be emitted in | 618 // when constant pool is full, but that needs to be emitted in |
| 609 // OutputJump too. | 619 // OutputJump too. |
| 610 UNIMPLEMENTED(); | 620 UNIMPLEMENTED(); |
| 611 } | 621 } |
| 612 } | 622 } |
| 613 } | 623 } |
| 614 | 624 |
| 615 | 625 |
| 626 // static |
| 627 Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { |
| 628 switch (jump_bytecode) { |
| 629 case Bytecode::kJump: |
| 630 case Bytecode::kJumpIfNull: |
| 631 case Bytecode::kJumpIfUndefined: |
| 632 return jump_bytecode; |
| 633 case Bytecode::kJumpIfTrue: |
| 634 return Bytecode::kJumpIfToBooleanTrue; |
| 635 case Bytecode::kJumpIfFalse: |
| 636 return Bytecode::kJumpIfToBooleanFalse; |
| 637 default: |
| 638 UNREACHABLE(); |
| 639 } |
| 640 return static_cast<Bytecode>(-1); |
| 641 } |
| 642 |
| 643 |
| 616 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 644 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
| 617 BytecodeLabel* label) { | 645 BytecodeLabel* label) { |
| 646 // Check if the value in accumulator is boolean, if not choose an |
| 647 // appropriate JumpIfToBoolean bytecode. |
| 648 if (NeedToBooleanCast()) { |
| 649 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); |
| 650 } |
| 651 |
| 618 int delta; | 652 int delta; |
| 619 if (label->is_bound()) { | 653 if (label->is_bound()) { |
| 620 // Label has been bound already so this is a backwards jump. | 654 // Label has been bound already so this is a backwards jump. |
| 621 CHECK_GE(bytecodes()->size(), label->offset()); | 655 CHECK_GE(bytecodes()->size(), label->offset()); |
| 622 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); | 656 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); |
| 623 size_t abs_delta = bytecodes()->size() - label->offset(); | 657 size_t abs_delta = bytecodes()->size() - label->offset(); |
| 624 delta = -static_cast<int>(abs_delta); | 658 delta = -static_cast<int>(abs_delta); |
| 625 } else { | 659 } else { |
| 626 // Label has not yet been bound so this is a forward reference | 660 // Label has not yet been bound so this is a forward reference |
| 627 // that will be patched when the label is bound. | 661 // that will be patched when the label is bound. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 652 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 686 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { |
| 653 return OutputJump(Bytecode::kJumpIfTrue, label); | 687 return OutputJump(Bytecode::kJumpIfTrue, label); |
| 654 } | 688 } |
| 655 | 689 |
| 656 | 690 |
| 657 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | 691 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { |
| 658 return OutputJump(Bytecode::kJumpIfFalse, label); | 692 return OutputJump(Bytecode::kJumpIfFalse, label); |
| 659 } | 693 } |
| 660 | 694 |
| 661 | 695 |
| 662 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfToBooleanTrue( | |
| 663 BytecodeLabel* label) { | |
| 664 return OutputJump(Bytecode::kJumpIfToBooleanTrue, label); | |
| 665 } | |
| 666 | |
| 667 | |
| 668 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfToBooleanFalse( | |
| 669 BytecodeLabel* label) { | |
| 670 return OutputJump(Bytecode::kJumpIfToBooleanFalse, label); | |
| 671 } | |
| 672 | |
| 673 | |
| 674 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { | 696 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { |
| 675 return OutputJump(Bytecode::kJumpIfNull, label); | 697 return OutputJump(Bytecode::kJumpIfNull, label); |
| 676 } | 698 } |
| 677 | 699 |
| 678 | 700 |
| 679 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( | 701 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( |
| 680 BytecodeLabel* label) { | 702 BytecodeLabel* label) { |
| 681 return OutputJump(Bytecode::kJumpIfUndefined, label); | 703 return OutputJump(Bytecode::kJumpIfUndefined, label); |
| 682 } | 704 } |
| 683 | 705 |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1217 DCHECK_GT(next_consecutive_count_, 0); | 1239 DCHECK_GT(next_consecutive_count_, 0); |
| 1218 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); | 1240 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); |
| 1219 allocated_.push_back(next_consecutive_register_); | 1241 allocated_.push_back(next_consecutive_register_); |
| 1220 next_consecutive_count_--; | 1242 next_consecutive_count_--; |
| 1221 return Register(next_consecutive_register_++); | 1243 return Register(next_consecutive_register_++); |
| 1222 } | 1244 } |
| 1223 | 1245 |
| 1224 } // namespace interpreter | 1246 } // namespace interpreter |
| 1225 } // namespace internal | 1247 } // namespace internal |
| 1226 } // namespace v8 | 1248 } // namespace v8 |
| OLD | NEW |