Chromium Code Reviews| 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 |