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