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 |