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/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/builtins/builtins-constructor.h" | 9 #include "src/builtins/builtins-constructor.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 int depth = execution_context()->ContextChainDepth(variable->scope()); | 1935 int depth = execution_context()->ContextChainDepth(variable->scope()); |
1936 ContextScope* context = execution_context()->Previous(depth); | 1936 ContextScope* context = execution_context()->Previous(depth); |
1937 Register context_reg; | 1937 Register context_reg; |
1938 if (context) { | 1938 if (context) { |
1939 context_reg = context->reg(); | 1939 context_reg = context->reg(); |
1940 depth = 0; | 1940 depth = 0; |
1941 } else { | 1941 } else { |
1942 context_reg = execution_context()->reg(); | 1942 context_reg = execution_context()->reg(); |
1943 } | 1943 } |
1944 | 1944 |
1945 BytecodeArrayBuilder::ContextSlotMutability immutable = | 1945 builder()->LoadContextSlot(context_reg, variable->index(), depth); |
1946 (variable->maybe_assigned() == kNotAssigned) | |
1947 ? BytecodeArrayBuilder::kImmutableSlot | |
1948 : BytecodeArrayBuilder::kMutableSlot; | |
1949 | |
1950 builder()->LoadContextSlot(context_reg, variable->index(), depth, | |
1951 immutable); | |
1952 if (hole_check_mode == HoleCheckMode::kRequired) { | 1946 if (hole_check_mode == HoleCheckMode::kRequired) { |
1953 BuildThrowIfHole(variable->name()); | 1947 BuildThrowIfHole(variable->name()); |
1954 } | 1948 } |
1955 break; | 1949 break; |
1956 } | 1950 } |
1957 case VariableLocation::LOOKUP: { | 1951 case VariableLocation::LOOKUP: { |
1958 switch (variable->mode()) { | 1952 switch (variable->mode()) { |
1959 case DYNAMIC_LOCAL: { | 1953 case DYNAMIC_LOCAL: { |
1960 Variable* local_variable = variable->local_if_not_shadowed(); | 1954 Variable* local_variable = variable->local_if_not_shadowed(); |
1961 int depth = | 1955 int depth = |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2105 depth = 0; | 2099 depth = 0; |
2106 } else { | 2100 } else { |
2107 context_reg = execution_context()->reg(); | 2101 context_reg = execution_context()->reg(); |
2108 } | 2102 } |
2109 | 2103 |
2110 if (hole_check_mode == HoleCheckMode::kRequired) { | 2104 if (hole_check_mode == HoleCheckMode::kRequired) { |
2111 // Load destination to check for hole. | 2105 // Load destination to check for hole. |
2112 Register value_temp = register_allocator()->NewRegister(); | 2106 Register value_temp = register_allocator()->NewRegister(); |
2113 builder() | 2107 builder() |
2114 ->StoreAccumulatorInRegister(value_temp) | 2108 ->StoreAccumulatorInRegister(value_temp) |
2115 .LoadContextSlot(context_reg, variable->index(), depth, | 2109 .LoadContextSlot(context_reg, variable->index(), depth); |
2116 BytecodeArrayBuilder::kMutableSlot); | |
2117 | 2110 |
2118 BuildHoleCheckForVariableAssignment(variable, op); | 2111 BuildHoleCheckForVariableAssignment(variable, op); |
2119 builder()->LoadAccumulatorWithRegister(value_temp); | 2112 builder()->LoadAccumulatorWithRegister(value_temp); |
2120 } | 2113 } |
2121 | 2114 |
2122 if (mode != CONST || op == Token::INIT) { | 2115 if (mode != CONST || op == Token::INIT) { |
2123 builder()->StoreContextSlot(context_reg, variable->index(), depth); | 2116 builder()->StoreContextSlot(context_reg, variable->index(), depth); |
2124 } else if (variable->throw_on_const_assignment(language_mode())) { | 2117 } else if (variable->throw_on_const_assignment(language_mode())) { |
2125 builder()->CallRuntime(Runtime::kThrowConstAssignError); | 2118 builder()->CallRuntime(Runtime::kThrowConstAssignError); |
2126 } | 2119 } |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2737 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2730 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2738 Variable* variable = proxy->var(); | 2731 Variable* variable = proxy->var(); |
2739 DCHECK(is_sloppy(language_mode()) || variable->is_this()); | 2732 DCHECK(is_sloppy(language_mode()) || variable->is_this()); |
2740 switch (variable->location()) { | 2733 switch (variable->location()) { |
2741 case VariableLocation::UNALLOCATED: { | 2734 case VariableLocation::UNALLOCATED: { |
2742 // Global var, let, const or variables not explicitly declared. | 2735 // Global var, let, const or variables not explicitly declared. |
2743 Register native_context = register_allocator()->NewRegister(); | 2736 Register native_context = register_allocator()->NewRegister(); |
2744 Register global_object = register_allocator()->NewRegister(); | 2737 Register global_object = register_allocator()->NewRegister(); |
2745 builder() | 2738 builder() |
2746 ->LoadContextSlot(execution_context()->reg(), | 2739 ->LoadContextSlot(execution_context()->reg(), |
2747 Context::NATIVE_CONTEXT_INDEX, 0, | 2740 Context::NATIVE_CONTEXT_INDEX, 0) |
2748 BytecodeArrayBuilder::kMutableSlot) | |
2749 .StoreAccumulatorInRegister(native_context) | 2741 .StoreAccumulatorInRegister(native_context) |
2750 .LoadContextSlot(native_context, Context::EXTENSION_INDEX, 0, | 2742 .LoadContextSlot(native_context, Context::EXTENSION_INDEX, 0) |
2751 BytecodeArrayBuilder::kMutableSlot) | |
2752 .StoreAccumulatorInRegister(global_object) | 2743 .StoreAccumulatorInRegister(global_object) |
2753 .LoadLiteral(variable->name()) | 2744 .LoadLiteral(variable->name()) |
2754 .Delete(global_object, language_mode()); | 2745 .Delete(global_object, language_mode()); |
2755 break; | 2746 break; |
2756 } | 2747 } |
2757 case VariableLocation::PARAMETER: | 2748 case VariableLocation::PARAMETER: |
2758 case VariableLocation::LOCAL: | 2749 case VariableLocation::LOCAL: |
2759 case VariableLocation::CONTEXT: { | 2750 case VariableLocation::CONTEXT: { |
2760 // Deleting local var/let/const, context variables, and arguments | 2751 // Deleting local var/let/const, context variables, and arguments |
2761 // does not have any effect. | 2752 // does not have any effect. |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3253 void BytecodeGenerator::VisitFunctionClosureForContext() { | 3244 void BytecodeGenerator::VisitFunctionClosureForContext() { |
3254 ValueResultScope value_execution_result(this); | 3245 ValueResultScope value_execution_result(this); |
3255 DeclarationScope* closure_scope = | 3246 DeclarationScope* closure_scope = |
3256 execution_context()->scope()->GetClosureScope(); | 3247 execution_context()->scope()->GetClosureScope(); |
3257 if (closure_scope->is_script_scope()) { | 3248 if (closure_scope->is_script_scope()) { |
3258 // Contexts nested in the native context have a canonical empty function as | 3249 // Contexts nested in the native context have a canonical empty function as |
3259 // their closure, not the anonymous closure containing the global code. | 3250 // their closure, not the anonymous closure containing the global code. |
3260 Register native_context = register_allocator()->NewRegister(); | 3251 Register native_context = register_allocator()->NewRegister(); |
3261 builder() | 3252 builder() |
3262 ->LoadContextSlot(execution_context()->reg(), | 3253 ->LoadContextSlot(execution_context()->reg(), |
3263 Context::NATIVE_CONTEXT_INDEX, 0, | 3254 Context::NATIVE_CONTEXT_INDEX, 0) |
3264 BytecodeArrayBuilder::kMutableSlot) | |
3265 .StoreAccumulatorInRegister(native_context) | 3255 .StoreAccumulatorInRegister(native_context) |
3266 .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0, | 3256 .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0); |
3267 BytecodeArrayBuilder::kMutableSlot); | |
3268 } else if (closure_scope->is_eval_scope()) { | 3257 } else if (closure_scope->is_eval_scope()) { |
3269 // Contexts created by a call to eval have the same closure as the | 3258 // Contexts created by a call to eval have the same closure as the |
3270 // context calling eval, not the anonymous closure containing the eval | 3259 // context calling eval, not the anonymous closure containing the eval |
3271 // code. Fetch it from the context. | 3260 // code. Fetch it from the context. |
3272 builder()->LoadContextSlot(execution_context()->reg(), | 3261 builder()->LoadContextSlot(execution_context()->reg(), |
3273 Context::CLOSURE_INDEX, 0, | 3262 Context::CLOSURE_INDEX, 0); |
3274 BytecodeArrayBuilder::kMutableSlot); | |
3275 } else { | 3263 } else { |
3276 DCHECK(closure_scope->is_function_scope() || | 3264 DCHECK(closure_scope->is_function_scope() || |
3277 closure_scope->is_module_scope()); | 3265 closure_scope->is_module_scope()); |
3278 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 3266 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
3279 } | 3267 } |
3280 } | 3268 } |
3281 | 3269 |
3282 // Visits the expression |expr| and places the result in the accumulator. | 3270 // Visits the expression |expr| and places the result in the accumulator. |
3283 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { | 3271 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { |
3284 ValueResultScope accumulator_scope(this); | 3272 ValueResultScope accumulator_scope(this); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3389 } | 3377 } |
3390 | 3378 |
3391 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3379 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3392 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3380 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3393 : Runtime::kStoreKeyedToSuper_Sloppy; | 3381 : Runtime::kStoreKeyedToSuper_Sloppy; |
3394 } | 3382 } |
3395 | 3383 |
3396 } // namespace interpreter | 3384 } // namespace interpreter |
3397 } // namespace internal | 3385 } // namespace internal |
3398 } // namespace v8 | 3386 } // namespace v8 |
OLD | NEW |