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-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include <stack> | 7 #include <stack> |
8 | 8 |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 | 647 |
648 void BytecodeGenerator::VisitProperty(Property* expr) { | 648 void BytecodeGenerator::VisitProperty(Property* expr) { |
649 TemporaryRegisterScope temporary_register_scope(&builder_); | 649 TemporaryRegisterScope temporary_register_scope(&builder_); |
650 Register obj = temporary_register_scope.NewRegister(); | 650 Register obj = temporary_register_scope.NewRegister(); |
651 Visit(expr->obj()); | 651 Visit(expr->obj()); |
652 builder()->StoreAccumulatorInRegister(obj); | 652 builder()->StoreAccumulatorInRegister(obj); |
653 VisitPropertyLoad(obj, expr); | 653 VisitPropertyLoad(obj, expr); |
654 } | 654 } |
655 | 655 |
656 | 656 |
657 Register BytecodeGenerator::VisitArguments( | |
658 ZoneList<Expression*>* args, TemporaryRegisterScope* register_scope) { | |
659 // Visit arguments and place in a contiguous block of temporary registers. | |
660 // Return the first temporary register corresponding to the first argument. | |
661 DCHECK_GT(args->length(), 0); | |
662 Register first_arg = register_scope->NewRegister(); | |
663 Visit(args->at(0)); | |
664 builder()->StoreAccumulatorInRegister(first_arg); | |
665 for (int i = 1; i < static_cast<int>(args->length()); i++) { | |
666 Register ith_arg = register_scope->NewRegister(); | |
667 Visit(args->at(i)); | |
668 builder()->StoreAccumulatorInRegister(ith_arg); | |
669 DCHECK(ith_arg.index() - i == first_arg.index()); | |
670 } | |
671 | |
672 return first_arg; | |
673 } | |
674 | |
675 | |
657 void BytecodeGenerator::VisitCall(Call* expr) { | 676 void BytecodeGenerator::VisitCall(Call* expr) { |
658 Expression* callee_expr = expr->expression(); | 677 Expression* callee_expr = expr->expression(); |
659 Call::CallType call_type = expr->GetCallType(isolate()); | 678 Call::CallType call_type = expr->GetCallType(isolate()); |
660 | 679 |
661 // Prepare the callee and the receiver to the function call. This depends on | 680 // Prepare the callee and the receiver to the function call. This depends on |
662 // the semantics of the underlying call type. | 681 // the semantics of the underlying call type. |
663 TemporaryRegisterScope temporary_register_scope(&builder_); | 682 TemporaryRegisterScope temporary_register_scope(&builder_); |
664 Register callee = temporary_register_scope.NewRegister(); | 683 Register callee = temporary_register_scope.NewRegister(); |
665 Register receiver = temporary_register_scope.NewRegister(); | 684 Register receiver = temporary_register_scope.NewRegister(); |
666 | 685 |
(...skipping 27 matching lines...) Expand all Loading... | |
694 } | 713 } |
695 case Call::LOOKUP_SLOT_CALL: | 714 case Call::LOOKUP_SLOT_CALL: |
696 case Call::SUPER_CALL: | 715 case Call::SUPER_CALL: |
697 case Call::POSSIBLY_EVAL_CALL: | 716 case Call::POSSIBLY_EVAL_CALL: |
698 UNIMPLEMENTED(); | 717 UNIMPLEMENTED(); |
699 } | 718 } |
700 | 719 |
701 // Evaluate all arguments to the function call and store in sequential | 720 // Evaluate all arguments to the function call and store in sequential |
702 // registers. | 721 // registers. |
703 ZoneList<Expression*>* args = expr->arguments(); | 722 ZoneList<Expression*>* args = expr->arguments(); |
704 for (int i = 0; i < args->length(); ++i) { | 723 if (args->length() > 0) { |
705 Visit(args->at(i)); | 724 Register first_arg = VisitArguments(args, &temporary_register_scope); |
706 Register arg = temporary_register_scope.NewRegister(); | 725 CHECK_EQ(first_arg.index(), receiver.index() + 1); |
707 DCHECK(arg.index() - i == receiver.index() + 1); | |
708 builder()->StoreAccumulatorInRegister(arg); | |
709 } | 726 } |
710 | 727 |
711 // TODO(rmcilroy): Deal with possible direct eval here? | 728 // TODO(rmcilroy): Deal with possible direct eval here? |
712 // TODO(rmcilroy): Use CallIC to allow call type feedback. | 729 // TODO(rmcilroy): Use CallIC to allow call type feedback. |
713 builder()->Call(callee, receiver, args->length()); | 730 builder()->Call(callee, receiver, args->length()); |
714 } | 731 } |
715 | 732 |
716 | 733 |
717 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); } | 734 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
735 TemporaryRegisterScope temporary_register_scope(builder()); | |
736 Register constructor = temporary_register_scope.NewRegister(); | |
737 Visit(expr->expression()); | |
738 builder()->StoreAccumulatorInRegister(constructor); | |
739 ZoneList<Expression*>* args = expr->arguments(); | |
740 if (args->length() > 0) { | |
741 Register first_arg = VisitArguments(args, &temporary_register_scope); | |
742 builder()->New(constructor, first_arg, args->length()); | |
743 } else { | |
744 builder()->New(constructor, constructor, 0); | |
rmcilroy
2015/10/14 10:18:34
nit - I think it deserves a comment that you are p
oth
2015/10/14 16:02:19
Done.
| |
745 } | |
746 } | |
718 | 747 |
719 | 748 |
720 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 749 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
721 if (expr->is_jsruntime()) { | 750 if (expr->is_jsruntime()) { |
722 UNIMPLEMENTED(); | 751 UNIMPLEMENTED(); |
723 } | 752 } |
724 | 753 |
725 // Evaluate all arguments to the runtime call. | 754 // Evaluate all arguments to the runtime call. |
726 ZoneList<Expression*>* args = expr->arguments(); | |
727 TemporaryRegisterScope temporary_register_scope(&builder_); | 755 TemporaryRegisterScope temporary_register_scope(&builder_); |
728 // Ensure we always have a valid first_arg register even if there are no | |
729 // arguments to pass. | |
730 Register first_arg = temporary_register_scope.NewRegister(); | |
731 for (int i = 0; i < args->length(); ++i) { | |
732 Register arg = | |
733 (i == 0) ? first_arg : temporary_register_scope.NewRegister(); | |
734 Visit(args->at(i)); | |
735 DCHECK_EQ(arg.index() - i, first_arg.index()); | |
736 builder()->StoreAccumulatorInRegister(arg); | |
737 } | |
738 | 756 |
739 // TODO(rmcilroy): support multiple return values. | 757 // TODO(rmcilroy): support multiple return values. |
740 DCHECK_LE(expr->function()->result_size, 1); | 758 DCHECK_LE(expr->function()->result_size, 1); |
741 Runtime::FunctionId function_id = expr->function()->function_id; | 759 Runtime::FunctionId function_id = expr->function()->function_id; |
760 ZoneList<Expression*>* args = expr->arguments(); | |
761 Register first_arg; | |
762 if (args->length() > 0) { | |
763 first_arg = VisitArguments(args, &temporary_register_scope); | |
764 } else { | |
765 first_arg = temporary_register_scope.NewRegister(); | |
rmcilroy
2015/10/14 10:18:34
ditto
oth
2015/10/14 16:02:19
Done.
| |
766 } | |
742 builder()->CallRuntime(function_id, first_arg, args->length()); | 767 builder()->CallRuntime(function_id, first_arg, args->length()); |
743 } | 768 } |
744 | 769 |
745 | 770 |
746 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { | 771 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { |
747 Visit(expr->expression()); | 772 Visit(expr->expression()); |
748 builder()->LoadUndefined(); | 773 builder()->LoadUndefined(); |
749 } | 774 } |
750 | 775 |
751 | 776 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
867 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 892 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
868 return info()->feedback_vector()->GetIndex(slot); | 893 return info()->feedback_vector()->GetIndex(slot); |
869 } | 894 } |
870 | 895 |
871 | 896 |
872 Register BytecodeGenerator::current_context() const { return current_context_; } | 897 Register BytecodeGenerator::current_context() const { return current_context_; } |
873 | 898 |
874 } // namespace interpreter | 899 } // namespace interpreter |
875 } // namespace internal | 900 } // namespace internal |
876 } // namespace v8 | 901 } // namespace v8 |
OLD | NEW |