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