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 "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 } | 724 } |
725 | 725 |
726 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | 726 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { |
727 Variable* variable = decl->proxy()->var(); | 727 Variable* variable = decl->proxy()->var(); |
728 VariableMode mode = decl->mode(); | 728 VariableMode mode = decl->mode(); |
729 // Const and let variables are initialized with the hole so that we can | 729 // Const and let variables are initialized with the hole so that we can |
730 // check that they are only assigned once. | 730 // check that they are only assigned once. |
731 bool hole_init = mode == CONST || mode == LET; | 731 bool hole_init = mode == CONST || mode == LET; |
732 switch (variable->location()) { | 732 switch (variable->location()) { |
733 case VariableLocation::GLOBAL: | 733 case VariableLocation::GLOBAL: |
734 case VariableLocation::UNALLOCATED: | 734 case VariableLocation::UNALLOCATED: { |
735 DCHECK(!variable->binding_needs_init()); | 735 DCHECK(!variable->binding_needs_init()); |
736 globals()->push_back(variable->name()); | 736 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
| 737 DCHECK(!slot.IsInvalid()); |
| 738 globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate())); |
737 globals()->push_back(isolate()->factory()->undefined_value()); | 739 globals()->push_back(isolate()->factory()->undefined_value()); |
738 break; | 740 break; |
| 741 } |
739 case VariableLocation::LOCAL: | 742 case VariableLocation::LOCAL: |
740 if (hole_init) { | 743 if (hole_init) { |
741 Register destination(variable->index()); | 744 Register destination(variable->index()); |
742 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); | 745 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); |
743 } | 746 } |
744 break; | 747 break; |
745 case VariableLocation::PARAMETER: | 748 case VariableLocation::PARAMETER: |
746 if (hole_init) { | 749 if (hole_init) { |
747 // The parameter indices are shifted by 1 (receiver is variable | 750 // The parameter indices are shifted by 1 (receiver is variable |
748 // index -1 but is parameter index 0 in BytecodeArrayBuilder). | 751 // index -1 but is parameter index 0 in BytecodeArrayBuilder). |
(...skipping 24 matching lines...) Expand all Loading... |
773 | 776 |
774 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 777 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
775 Variable* variable = decl->proxy()->var(); | 778 Variable* variable = decl->proxy()->var(); |
776 switch (variable->location()) { | 779 switch (variable->location()) { |
777 case VariableLocation::GLOBAL: | 780 case VariableLocation::GLOBAL: |
778 case VariableLocation::UNALLOCATED: { | 781 case VariableLocation::UNALLOCATED: { |
779 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( | 782 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( |
780 decl->fun(), info()->script(), info()); | 783 decl->fun(), info()->script(), info()); |
781 // Check for stack-overflow exception. | 784 // Check for stack-overflow exception. |
782 if (function.is_null()) return SetStackOverflow(); | 785 if (function.is_null()) return SetStackOverflow(); |
783 globals()->push_back(variable->name()); | 786 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
| 787 DCHECK(!slot.IsInvalid()); |
| 788 globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate())); |
784 globals()->push_back(function); | 789 globals()->push_back(function); |
785 break; | 790 break; |
786 } | 791 } |
787 case VariableLocation::PARAMETER: | 792 case VariableLocation::PARAMETER: |
788 case VariableLocation::LOCAL: { | 793 case VariableLocation::LOCAL: { |
789 VisitForAccumulatorValue(decl->fun()); | 794 VisitForAccumulatorValue(decl->fun()); |
790 DCHECK(variable->mode() == LET || variable->mode() == VAR || | 795 DCHECK(variable->mode() == LET || variable->mode() == VAR || |
791 variable->mode() == CONST); | 796 variable->mode() == CONST); |
792 VisitVariableAssignment(variable, Token::INIT, | 797 VisitVariableAssignment(variable, Token::INIT, |
793 FeedbackVectorSlot::Invalid()); | 798 FeedbackVectorSlot::Invalid()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 RegisterAllocationScope register_scope(this); | 830 RegisterAllocationScope register_scope(this); |
826 Visit(declarations->at(i)); | 831 Visit(declarations->at(i)); |
827 } | 832 } |
828 if (globals()->empty()) return; | 833 if (globals()->empty()) return; |
829 int array_index = 0; | 834 int array_index = 0; |
830 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( | 835 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( |
831 static_cast<int>(globals()->size()), TENURED); | 836 static_cast<int>(globals()->size()), TENURED); |
832 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); | 837 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); |
833 int encoded_flags = info()->GetDeclareGlobalsFlags(); | 838 int encoded_flags = info()->GetDeclareGlobalsFlags(); |
834 | 839 |
835 Register pairs = register_allocator()->NewRegister(); | 840 register_allocator()->PrepareForConsecutiveAllocations(3); |
| 841 |
| 842 Register pairs = register_allocator()->NextConsecutiveRegister(); |
836 builder()->LoadLiteral(data); | 843 builder()->LoadLiteral(data); |
837 builder()->StoreAccumulatorInRegister(pairs); | 844 builder()->StoreAccumulatorInRegister(pairs); |
838 | 845 |
839 Register flags = register_allocator()->NewRegister(); | 846 Register flags = register_allocator()->NextConsecutiveRegister(); |
840 builder()->LoadLiteral(Smi::FromInt(encoded_flags)); | 847 builder()->LoadLiteral(Smi::FromInt(encoded_flags)); |
841 builder()->StoreAccumulatorInRegister(flags); | 848 builder()->StoreAccumulatorInRegister(flags); |
842 DCHECK(flags.index() == pairs.index() + 1); | 849 DCHECK(flags.index() == pairs.index() + 1); |
843 | 850 |
844 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2); | 851 Register function = register_allocator()->NextConsecutiveRegister(); |
| 852 builder()->MoveRegister(Register::function_closure(), function); |
| 853 |
| 854 builder()->CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3); |
845 globals()->clear(); | 855 globals()->clear(); |
846 } | 856 } |
847 | 857 |
848 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { | 858 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { |
849 for (int i = 0; i < statements->length(); i++) { | 859 for (int i = 0; i < statements->length(); i++) { |
850 // Allocate an outer register allocations scope for the statement. | 860 // Allocate an outer register allocations scope for the statement. |
851 RegisterAllocationScope allocation_scope(this); | 861 RegisterAllocationScope allocation_scope(this); |
852 Statement* stmt = statements->at(i); | 862 Statement* stmt = statements->at(i); |
853 Visit(stmt); | 863 Visit(stmt); |
854 if (stmt->IsJump()) break; | 864 if (stmt->IsJump()) break; |
(...skipping 2319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3174 return execution_context()->scope()->language_mode(); | 3184 return execution_context()->scope()->language_mode(); |
3175 } | 3185 } |
3176 | 3186 |
3177 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3187 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
3178 return TypeFeedbackVector::GetIndex(slot); | 3188 return TypeFeedbackVector::GetIndex(slot); |
3179 } | 3189 } |
3180 | 3190 |
3181 } // namespace interpreter | 3191 } // namespace interpreter |
3182 } // namespace internal | 3192 } // namespace internal |
3183 } // namespace v8 | 3193 } // namespace v8 |
OLD | NEW |