| 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 |