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/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 if (stmt->scope() != nullptr) { | 894 if (stmt->scope() != nullptr) { |
895 VisitDeclarations(stmt->scope()->declarations()); | 895 VisitDeclarations(stmt->scope()->declarations()); |
896 } | 896 } |
897 VisitStatements(stmt->statements()); | 897 VisitStatements(stmt->statements()); |
898 if (stmt->labels() != nullptr) block_builder.EndBlock(); | 898 if (stmt->labels() != nullptr) block_builder.EndBlock(); |
899 } | 899 } |
900 | 900 |
901 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | 901 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { |
902 Variable* variable = decl->proxy()->var(); | 902 Variable* variable = decl->proxy()->var(); |
903 switch (variable->location()) { | 903 switch (variable->location()) { |
904 case VariableLocation::GLOBAL: | |
905 case VariableLocation::UNALLOCATED: { | 904 case VariableLocation::UNALLOCATED: { |
906 DCHECK(!variable->binding_needs_init()); | 905 DCHECK(!variable->binding_needs_init()); |
907 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 906 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
908 globals_builder()->AddUndefinedDeclaration(slot); | 907 globals_builder()->AddUndefinedDeclaration(slot); |
909 break; | 908 break; |
910 } | 909 } |
911 case VariableLocation::LOCAL: | 910 case VariableLocation::LOCAL: |
912 if (variable->binding_needs_init()) { | 911 if (variable->binding_needs_init()) { |
913 Register destination(variable->index()); | 912 Register destination(variable->index()); |
914 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); | 913 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); |
(...skipping 26 matching lines...) Expand all Loading... |
941 break; | 940 break; |
942 } | 941 } |
943 case VariableLocation::MODULE: | 942 case VariableLocation::MODULE: |
944 UNREACHABLE(); | 943 UNREACHABLE(); |
945 } | 944 } |
946 } | 945 } |
947 | 946 |
948 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 947 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
949 Variable* variable = decl->proxy()->var(); | 948 Variable* variable = decl->proxy()->var(); |
950 switch (variable->location()) { | 949 switch (variable->location()) { |
951 case VariableLocation::GLOBAL: | |
952 case VariableLocation::UNALLOCATED: { | 950 case VariableLocation::UNALLOCATED: { |
953 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 951 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
954 globals_builder()->AddFunctionDeclaration(slot, decl->fun()); | 952 globals_builder()->AddFunctionDeclaration(slot, decl->fun()); |
955 break; | 953 break; |
956 } | 954 } |
957 case VariableLocation::PARAMETER: | 955 case VariableLocation::PARAMETER: |
958 case VariableLocation::LOCAL: { | 956 case VariableLocation::LOCAL: { |
959 VisitForAccumulatorValue(decl->fun()); | 957 VisitForAccumulatorValue(decl->fun()); |
960 DCHECK(variable->mode() == LET || variable->mode() == VAR || | 958 DCHECK(variable->mode() == LET || variable->mode() == VAR || |
961 variable->mode() == CONST); | 959 variable->mode() == CONST); |
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1946 // The parameter indices are shifted by 1 (receiver is variable | 1944 // The parameter indices are shifted by 1 (receiver is variable |
1947 // index -1 but is parameter index 0 in BytecodeArrayBuilder). | 1945 // index -1 but is parameter index 0 in BytecodeArrayBuilder). |
1948 Register source = builder()->Parameter(variable->index() + 1); | 1946 Register source = builder()->Parameter(variable->index() + 1); |
1949 // We need to load the variable into the accumulator, even when in a | 1947 // We need to load the variable into the accumulator, even when in a |
1950 // VisitForRegisterScope, in order to avoid register aliasing if | 1948 // VisitForRegisterScope, in order to avoid register aliasing if |
1951 // subsequent expressions assign to the same variable. | 1949 // subsequent expressions assign to the same variable. |
1952 builder()->LoadAccumulatorWithRegister(source); | 1950 builder()->LoadAccumulatorWithRegister(source); |
1953 BuildHoleCheckForVariableLoad(variable); | 1951 BuildHoleCheckForVariableLoad(variable); |
1954 break; | 1952 break; |
1955 } | 1953 } |
1956 case VariableLocation::GLOBAL: | |
1957 case VariableLocation::UNALLOCATED: { | 1954 case VariableLocation::UNALLOCATED: { |
1958 builder()->LoadGlobal(feedback_index(slot), typeof_mode); | 1955 builder()->LoadGlobal(feedback_index(slot), typeof_mode); |
1959 break; | 1956 break; |
1960 } | 1957 } |
1961 case VariableLocation::CONTEXT: { | 1958 case VariableLocation::CONTEXT: { |
1962 int depth = execution_context()->ContextChainDepth(variable->scope()); | 1959 int depth = execution_context()->ContextChainDepth(variable->scope()); |
1963 ContextScope* context = execution_context()->Previous(depth); | 1960 ContextScope* context = execution_context()->Previous(depth); |
1964 Register context_reg; | 1961 Register context_reg; |
1965 if (context) { | 1962 if (context) { |
1966 context_reg = context->reg(); | 1963 context_reg = context->reg(); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2127 builder()->LoadAccumulatorWithRegister(value_temp); | 2124 builder()->LoadAccumulatorWithRegister(value_temp); |
2128 } | 2125 } |
2129 | 2126 |
2130 if (mode != CONST || op == Token::INIT) { | 2127 if (mode != CONST || op == Token::INIT) { |
2131 builder()->StoreAccumulatorInRegister(destination); | 2128 builder()->StoreAccumulatorInRegister(destination); |
2132 } else if (variable->throw_on_const_assignment(language_mode())) { | 2129 } else if (variable->throw_on_const_assignment(language_mode())) { |
2133 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); | 2130 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); |
2134 } | 2131 } |
2135 break; | 2132 break; |
2136 } | 2133 } |
2137 case VariableLocation::GLOBAL: | |
2138 case VariableLocation::UNALLOCATED: { | 2134 case VariableLocation::UNALLOCATED: { |
2139 builder()->StoreGlobal(variable->name(), feedback_index(slot), | 2135 builder()->StoreGlobal(variable->name(), feedback_index(slot), |
2140 language_mode()); | 2136 language_mode()); |
2141 break; | 2137 break; |
2142 } | 2138 } |
2143 case VariableLocation::CONTEXT: { | 2139 case VariableLocation::CONTEXT: { |
2144 int depth = execution_context()->ContextChainDepth(variable->scope()); | 2140 int depth = execution_context()->ContextChainDepth(variable->scope()); |
2145 ContextScope* context = execution_context()->Previous(depth); | 2141 ContextScope* context = execution_context()->Previous(depth); |
2146 Register context_reg; | 2142 Register context_reg; |
2147 | 2143 |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2825 Register object = VisitForRegisterValue(property->obj()); | 2821 Register object = VisitForRegisterValue(property->obj()); |
2826 VisitForAccumulatorValue(property->key()); | 2822 VisitForAccumulatorValue(property->key()); |
2827 builder()->Delete(object, language_mode()); | 2823 builder()->Delete(object, language_mode()); |
2828 } else if (expr->expression()->IsVariableProxy()) { | 2824 } else if (expr->expression()->IsVariableProxy()) { |
2829 // Delete of an unqualified identifier is allowed in sloppy mode but is | 2825 // Delete of an unqualified identifier is allowed in sloppy mode but is |
2830 // not allowed in strict mode. Deleting 'this' is allowed in both modes. | 2826 // not allowed in strict mode. Deleting 'this' is allowed in both modes. |
2831 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2827 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2832 Variable* variable = proxy->var(); | 2828 Variable* variable = proxy->var(); |
2833 DCHECK(is_sloppy(language_mode()) || variable->is_this()); | 2829 DCHECK(is_sloppy(language_mode()) || variable->is_this()); |
2834 switch (variable->location()) { | 2830 switch (variable->location()) { |
2835 case VariableLocation::GLOBAL: | |
2836 case VariableLocation::UNALLOCATED: { | 2831 case VariableLocation::UNALLOCATED: { |
2837 // Global var, let, const or variables not explicitly declared. | 2832 // Global var, let, const or variables not explicitly declared. |
2838 Register native_context = register_allocator()->NewRegister(); | 2833 Register native_context = register_allocator()->NewRegister(); |
2839 Register global_object = register_allocator()->NewRegister(); | 2834 Register global_object = register_allocator()->NewRegister(); |
2840 builder() | 2835 builder() |
2841 ->LoadContextSlot(execution_context()->reg(), | 2836 ->LoadContextSlot(execution_context()->reg(), |
2842 Context::NATIVE_CONTEXT_INDEX) | 2837 Context::NATIVE_CONTEXT_INDEX) |
2843 .StoreAccumulatorInRegister(native_context) | 2838 .StoreAccumulatorInRegister(native_context) |
2844 .LoadContextSlot(native_context, Context::EXTENSION_INDEX) | 2839 .LoadContextSlot(native_context, Context::EXTENSION_INDEX) |
2845 .StoreAccumulatorInRegister(global_object) | 2840 .StoreAccumulatorInRegister(global_object) |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3390 return execution_context()->scope()->language_mode(); | 3385 return execution_context()->scope()->language_mode(); |
3391 } | 3386 } |
3392 | 3387 |
3393 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3388 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
3394 return TypeFeedbackVector::GetIndex(slot); | 3389 return TypeFeedbackVector::GetIndex(slot); |
3395 } | 3390 } |
3396 | 3391 |
3397 } // namespace interpreter | 3392 } // namespace interpreter |
3398 } // namespace internal | 3393 } // namespace internal |
3399 } // namespace v8 | 3394 } // namespace v8 |
OLD | NEW |