| 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/code-stubs.h" | 9 #include "src/code-stubs.h" | 
| 10 #include "src/compilation-info.h" | 10 #include "src/compilation-info.h" | 
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 736   // Initialize control scope. | 736   // Initialize control scope. | 
| 737   ControlScopeForTopLevel control(this); | 737   ControlScopeForTopLevel control(this); | 
| 738 | 738 | 
| 739   RegisterAllocationScope register_scope(this); | 739   RegisterAllocationScope register_scope(this); | 
| 740 | 740 | 
| 741   if (IsResumableFunction(info()->literal()->kind())) { | 741   if (IsResumableFunction(info()->literal()->kind())) { | 
| 742     generator_state_ = register_allocator()->NewRegister(); | 742     generator_state_ = register_allocator()->NewRegister(); | 
| 743     VisitGeneratorPrologue(); | 743     VisitGeneratorPrologue(); | 
| 744   } | 744   } | 
| 745 | 745 | 
| 746   // Build function context only if there are context allocated variables. |  | 
| 747   if (scope()->NeedsContext()) { | 746   if (scope()->NeedsContext()) { | 
| 748     // Push a new inner context scope for the function. | 747     // Push a new inner context scope for the function. | 
| 749     VisitNewLocalFunctionContext(); | 748     VisitNewLocalFunctionContext(); | 
| 750     ContextScope local_function_context(this, scope(), false); | 749     ContextScope local_function_context(this, scope(), false); | 
| 751     VisitBuildLocalActivationContext(); | 750     VisitBuildLocalActivationContext(); | 
| 752     GenerateBytecodeBody(); | 751     GenerateBytecodeBody(); | 
| 753   } else { | 752   } else { | 
| 754     GenerateBytecodeBody(); | 753     GenerateBytecodeBody(); | 
| 755   } | 754   } | 
| 756 | 755 | 
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 933 | 932 | 
| 934       Register name = register_allocator()->NewRegister(); | 933       Register name = register_allocator()->NewRegister(); | 
| 935 | 934 | 
| 936       builder() | 935       builder() | 
| 937           ->LoadLiteral(variable->name()) | 936           ->LoadLiteral(variable->name()) | 
| 938           .StoreAccumulatorInRegister(name) | 937           .StoreAccumulatorInRegister(name) | 
| 939           .CallRuntime(Runtime::kDeclareEvalVar, name, 1); | 938           .CallRuntime(Runtime::kDeclareEvalVar, name, 1); | 
| 940       break; | 939       break; | 
| 941     } | 940     } | 
| 942     case VariableLocation::MODULE: | 941     case VariableLocation::MODULE: | 
| 943       UNREACHABLE(); | 942       // Nothing to do here. | 
|  | 943       break; | 
| 944   } | 944   } | 
| 945 } | 945 } | 
| 946 | 946 | 
| 947 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 947 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 
| 948   Variable* variable = decl->proxy()->var(); | 948   Variable* variable = decl->proxy()->var(); | 
| 949   DCHECK(variable->mode() == LET || variable->mode() == VAR); | 949   DCHECK(variable->mode() == LET || variable->mode() == VAR); | 
| 950   switch (variable->location()) { | 950   switch (variable->location()) { | 
| 951     case VariableLocation::UNALLOCATED: { | 951     case VariableLocation::UNALLOCATED: { | 
| 952       FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 952       FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 
| 953       globals_builder()->AddFunctionDeclaration(slot, decl->fun()); | 953       globals_builder()->AddFunctionDeclaration(slot, decl->fun()); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 972       Register name = register_allocator()->NextConsecutiveRegister(); | 972       Register name = register_allocator()->NextConsecutiveRegister(); | 
| 973       Register literal = register_allocator()->NextConsecutiveRegister(); | 973       Register literal = register_allocator()->NextConsecutiveRegister(); | 
| 974       builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); | 974       builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); | 
| 975 | 975 | 
| 976       VisitForAccumulatorValue(decl->fun()); | 976       VisitForAccumulatorValue(decl->fun()); | 
| 977       builder()->StoreAccumulatorInRegister(literal).CallRuntime( | 977       builder()->StoreAccumulatorInRegister(literal).CallRuntime( | 
| 978           Runtime::kDeclareEvalFunction, name, 2); | 978           Runtime::kDeclareEvalFunction, name, 2); | 
| 979       break; | 979       break; | 
| 980     } | 980     } | 
| 981     case VariableLocation::MODULE: | 981     case VariableLocation::MODULE: | 
| 982       UNREACHABLE(); | 982       DCHECK(variable->mode() == LET); | 
|  | 983       VisitForAccumulatorValue(decl->fun()); | 
|  | 984       VisitVariableAssignment(variable, Token::INIT, | 
|  | 985                               FeedbackVectorSlot::Invalid()); | 
|  | 986       break; | 
| 983   } | 987   } | 
| 984 } | 988 } | 
| 985 | 989 | 
| 986 void BytecodeGenerator::VisitDeclarations( | 990 void BytecodeGenerator::VisitDeclarations( | 
| 987     ZoneList<Declaration*>* declarations) { | 991     ZoneList<Declaration*>* declarations) { | 
| 988   RegisterAllocationScope register_scope(this); | 992   RegisterAllocationScope register_scope(this); | 
| 989   DCHECK(globals_builder()->empty()); | 993   DCHECK(globals_builder()->empty()); | 
| 990   for (int i = 0; i < declarations->length(); i++) { | 994   for (int i = 0; i < declarations->length(); i++) { | 
| 991     RegisterAllocationScope register_scope(this); | 995     RegisterAllocationScope register_scope(this); | 
| 992     Visit(declarations->at(i)); | 996     Visit(declarations->at(i)); | 
| (...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1971       } | 1975       } | 
| 1972 | 1976 | 
| 1973       builder()->LoadContextSlot(context_reg, variable->index()); | 1977       builder()->LoadContextSlot(context_reg, variable->index()); | 
| 1974       BuildHoleCheckForVariableLoad(variable); | 1978       BuildHoleCheckForVariableLoad(variable); | 
| 1975       break; | 1979       break; | 
| 1976     } | 1980     } | 
| 1977     case VariableLocation::LOOKUP: { | 1981     case VariableLocation::LOOKUP: { | 
| 1978       builder()->LoadLookupSlot(variable->name(), typeof_mode); | 1982       builder()->LoadLookupSlot(variable->name(), typeof_mode); | 
| 1979       break; | 1983       break; | 
| 1980     } | 1984     } | 
| 1981     case VariableLocation::MODULE: | 1985     case VariableLocation::MODULE: { | 
| 1982       UNREACHABLE(); | 1986       ModuleDescriptor* descriptor = scope()->GetModuleScope()->module(); | 
|  | 1987       if (variable->IsExport()) { | 
|  | 1988         auto it = descriptor->regular_exports().find(variable->raw_name()); | 
|  | 1989         DCHECK(it != descriptor->regular_exports().end()); | 
|  | 1990         Register export_name = register_allocator()->NewRegister(); | 
|  | 1991         builder() | 
|  | 1992             ->LoadLiteral(it->second->export_name->string()) | 
|  | 1993             .StoreAccumulatorInRegister(export_name) | 
|  | 1994             .CallRuntime(Runtime::kLoadModuleExport, export_name, 1); | 
|  | 1995       } else { | 
|  | 1996         UNIMPLEMENTED(); | 
|  | 1997       } | 
|  | 1998       break; | 
|  | 1999     } | 
| 1983   } | 2000   } | 
| 1984   execution_result()->SetResultInAccumulator(); | 2001   execution_result()->SetResultInAccumulator(); | 
| 1985 } | 2002 } | 
| 1986 | 2003 | 
| 1987 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( | 2004 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( | 
| 1988     Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { | 2005     Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { | 
| 1989   AccumulatorResultScope accumulator_result(this); | 2006   AccumulatorResultScope accumulator_result(this); | 
| 1990   VisitVariableLoad(variable, slot, typeof_mode); | 2007   VisitVariableLoad(variable, slot, typeof_mode); | 
| 1991 } | 2008 } | 
| 1992 | 2009 | 
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2170         builder()->StoreContextSlot(context_reg, variable->index()); | 2187         builder()->StoreContextSlot(context_reg, variable->index()); | 
| 2171       } else if (variable->throw_on_const_assignment(language_mode())) { | 2188       } else if (variable->throw_on_const_assignment(language_mode())) { | 
| 2172         builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); | 2189         builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); | 
| 2173       } | 2190       } | 
| 2174       break; | 2191       break; | 
| 2175     } | 2192     } | 
| 2176     case VariableLocation::LOOKUP: { | 2193     case VariableLocation::LOOKUP: { | 
| 2177       builder()->StoreLookupSlot(variable->name(), language_mode()); | 2194       builder()->StoreLookupSlot(variable->name(), language_mode()); | 
| 2178       break; | 2195       break; | 
| 2179     } | 2196     } | 
| 2180     case VariableLocation::MODULE: | 2197     case VariableLocation::MODULE: { | 
| 2181       UNREACHABLE(); | 2198       DCHECK(IsDeclaredVariableMode(mode)); | 
|  | 2199 | 
|  | 2200       if (mode == CONST && op != Token::INIT) { | 
|  | 2201         builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); | 
|  | 2202         break; | 
|  | 2203       } | 
|  | 2204 | 
|  | 2205       // If we don't throw above, we know that we're dealing with an | 
|  | 2206       // export because imports are const and we do not generate initializing | 
|  | 2207       // assignments for them. | 
|  | 2208       DCHECK(variable->IsExport()); | 
|  | 2209 | 
|  | 2210       ModuleDescriptor* mod = scope()->GetModuleScope()->module(); | 
|  | 2211       auto it = mod->regular_exports().find(variable->raw_name()); | 
|  | 2212       DCHECK(it != mod->regular_exports().end()); | 
|  | 2213 | 
|  | 2214       register_allocator()->PrepareForConsecutiveAllocations(2); | 
|  | 2215       Register export_name = register_allocator()->NextConsecutiveRegister(); | 
|  | 2216       Register value = register_allocator()->NextConsecutiveRegister(); | 
|  | 2217       builder() | 
|  | 2218           ->StoreAccumulatorInRegister(value) | 
|  | 2219           .LoadLiteral(it->second->export_name->string()) | 
|  | 2220           .StoreAccumulatorInRegister(export_name) | 
|  | 2221           .CallRuntime(Runtime::kStoreModuleExport, export_name, 2); | 
|  | 2222       break; | 
|  | 2223     } | 
| 2182   } | 2224   } | 
| 2183 } | 2225 } | 
| 2184 | 2226 | 
| 2185 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 2227 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 
| 2186   DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 2228   DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 
| 2187   Register object, key, home_object, value; | 2229   Register object, key, home_object, value; | 
| 2188   Handle<String> name; | 2230   Handle<String> name; | 
| 2189 | 2231 | 
| 2190   // Left-hand side can only be a property, a global or a variable slot. | 2232   // Left-hand side can only be a property, a global or a variable slot. | 
| 2191   Property* property = expr->target()->AsProperty(); | 2233   Property* property = expr->target()->AsProperty(); | 
| (...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3128 } | 3170 } | 
| 3129 | 3171 | 
| 3130 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { | 3172 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { | 
| 3131   Visit(expr->expression()); | 3173   Visit(expr->expression()); | 
| 3132 } | 3174 } | 
| 3133 | 3175 | 
| 3134 void BytecodeGenerator::VisitNewLocalFunctionContext() { | 3176 void BytecodeGenerator::VisitNewLocalFunctionContext() { | 
| 3135   AccumulatorResultScope accumulator_execution_result(this); | 3177   AccumulatorResultScope accumulator_execution_result(this); | 
| 3136   Scope* scope = this->scope(); | 3178   Scope* scope = this->scope(); | 
| 3137 | 3179 | 
| 3138   // Allocate a new local context. | 3180   // Create the appropriate context. | 
| 3139   if (scope->is_script_scope()) { | 3181   if (scope->is_script_scope()) { | 
| 3140     RegisterAllocationScope register_scope(this); | 3182     RegisterAllocationScope register_scope(this); | 
| 3141     Register closure = register_allocator()->NewRegister(); | 3183     register_allocator()->PrepareForConsecutiveAllocations(2); | 
| 3142     Register scope_info = register_allocator()->NewRegister(); | 3184     Register closure = register_allocator()->NextConsecutiveRegister(); | 
| 3143     DCHECK(Register::AreContiguous(closure, scope_info)); | 3185     Register scope_info = register_allocator()->NextConsecutiveRegister(); | 
| 3144     builder() | 3186     builder() | 
| 3145         ->LoadAccumulatorWithRegister(Register::function_closure()) | 3187         ->LoadAccumulatorWithRegister(Register::function_closure()) | 
| 3146         .StoreAccumulatorInRegister(closure) | 3188         .StoreAccumulatorInRegister(closure) | 
| 3147         .LoadLiteral(scope->scope_info()) | 3189         .LoadLiteral(scope->scope_info()) | 
| 3148         .StoreAccumulatorInRegister(scope_info) | 3190         .StoreAccumulatorInRegister(scope_info) | 
| 3149         .CallRuntime(Runtime::kNewScriptContext, closure, 2); | 3191         .CallRuntime(Runtime::kNewScriptContext, closure, 2); | 
|  | 3192   } else if (scope->is_module_scope()) { | 
|  | 3193     // We don't need to do anything for the outer script scope. | 
|  | 3194     DCHECK(scope->outer_scope()->is_script_scope()); | 
|  | 3195 | 
|  | 3196     RegisterAllocationScope register_scope(this); | 
|  | 3197     register_allocator()->PrepareForConsecutiveAllocations(3); | 
|  | 3198     Register module = register_allocator()->NextConsecutiveRegister(); | 
|  | 3199     Register closure = register_allocator()->NextConsecutiveRegister(); | 
|  | 3200     Register scope_info = register_allocator()->NextConsecutiveRegister(); | 
|  | 3201     // A JSFunction representing a module is called with the module object as | 
|  | 3202     // its sole argument, which we pass on to PushModuleContext. | 
|  | 3203     builder() | 
|  | 3204         ->MoveRegister(builder()->Parameter(1), module) | 
|  | 3205         .LoadAccumulatorWithRegister(Register::function_closure()) | 
|  | 3206         .StoreAccumulatorInRegister(closure) | 
|  | 3207         .LoadLiteral(scope->scope_info()) | 
|  | 3208         .StoreAccumulatorInRegister(scope_info) | 
|  | 3209         .CallRuntime(Runtime::kPushModuleContext, module, 3); | 
| 3150   } else { | 3210   } else { | 
| 3151     int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 3211     int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 
| 3152     builder()->CreateFunctionContext(slot_count); | 3212     builder()->CreateFunctionContext(slot_count); | 
| 3153   } | 3213   } | 
| 3154   execution_result()->SetResultInAccumulator(); | 3214   execution_result()->SetResultInAccumulator(); | 
| 3155 } | 3215 } | 
| 3156 | 3216 | 
| 3157 void BytecodeGenerator::VisitBuildLocalActivationContext() { | 3217 void BytecodeGenerator::VisitBuildLocalActivationContext() { | 
| 3158   DeclarationScope* scope = this->scope(); | 3218   DeclarationScope* scope = this->scope(); | 
| 3159 | 3219 | 
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3286   // before a local variable containing the <new.target> is used. Using a label | 3346   // before a local variable containing the <new.target> is used. Using a label | 
| 3287   // as below flushes the entire pipeline, we should be more specific here. | 3347   // as below flushes the entire pipeline, we should be more specific here. | 
| 3288   BytecodeLabel flush_state_label; | 3348   BytecodeLabel flush_state_label; | 
| 3289   builder()->Bind(&flush_state_label); | 3349   builder()->Bind(&flush_state_label); | 
| 3290 } | 3350 } | 
| 3291 | 3351 | 
| 3292 void BytecodeGenerator::VisitFunctionClosureForContext() { | 3352 void BytecodeGenerator::VisitFunctionClosureForContext() { | 
| 3293   AccumulatorResultScope accumulator_execution_result(this); | 3353   AccumulatorResultScope accumulator_execution_result(this); | 
| 3294   DeclarationScope* closure_scope = | 3354   DeclarationScope* closure_scope = | 
| 3295       execution_context()->scope()->GetClosureScope(); | 3355       execution_context()->scope()->GetClosureScope(); | 
| 3296   if (closure_scope->is_script_scope() || | 3356   if (closure_scope->is_script_scope()) { | 
| 3297       closure_scope->is_module_scope()) { |  | 
| 3298     // Contexts nested in the native context have a canonical empty function as | 3357     // Contexts nested in the native context have a canonical empty function as | 
| 3299     // their closure, not the anonymous closure containing the global code. | 3358     // their closure, not the anonymous closure containing the global code. | 
| 3300     Register native_context = register_allocator()->NewRegister(); | 3359     Register native_context = register_allocator()->NewRegister(); | 
| 3301     builder() | 3360     builder() | 
| 3302         ->LoadContextSlot(execution_context()->reg(), | 3361         ->LoadContextSlot(execution_context()->reg(), | 
| 3303                           Context::NATIVE_CONTEXT_INDEX) | 3362                           Context::NATIVE_CONTEXT_INDEX) | 
| 3304         .StoreAccumulatorInRegister(native_context) | 3363         .StoreAccumulatorInRegister(native_context) | 
| 3305         .LoadContextSlot(native_context, Context::CLOSURE_INDEX); | 3364         .LoadContextSlot(native_context, Context::CLOSURE_INDEX); | 
| 3306   } else if (closure_scope->is_eval_scope()) { | 3365   } else if (closure_scope->is_eval_scope()) { | 
| 3307     // Contexts created by a call to eval have the same closure as the | 3366     // Contexts created by a call to eval have the same closure as the | 
| 3308     // context calling eval, not the anonymous closure containing the eval | 3367     // context calling eval, not the anonymous closure containing the eval | 
| 3309     // code. Fetch it from the context. | 3368     // code. Fetch it from the context. | 
| 3310     builder()->LoadContextSlot(execution_context()->reg(), | 3369     builder()->LoadContextSlot(execution_context()->reg(), | 
| 3311                                Context::CLOSURE_INDEX); | 3370                                Context::CLOSURE_INDEX); | 
| 3312   } else { | 3371   } else { | 
| 3313     DCHECK(closure_scope->is_function_scope()); | 3372     DCHECK(closure_scope->is_function_scope() || | 
|  | 3373            closure_scope->is_module_scope()); | 
| 3314     builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 3374     builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 
| 3315   } | 3375   } | 
| 3316   execution_result()->SetResultInAccumulator(); | 3376   execution_result()->SetResultInAccumulator(); | 
| 3317 } | 3377 } | 
| 3318 | 3378 | 
| 3319 // Visits the expression |expr| and places the result in the accumulator. | 3379 // Visits the expression |expr| and places the result in the accumulator. | 
| 3320 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { | 3380 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { | 
| 3321   AccumulatorResultScope accumulator_scope(this); | 3381   AccumulatorResultScope accumulator_scope(this); | 
| 3322   Visit(expr); | 3382   Visit(expr); | 
| 3323 } | 3383 } | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3393   return execution_context()->scope()->language_mode(); | 3453   return execution_context()->scope()->language_mode(); | 
| 3394 } | 3454 } | 
| 3395 | 3455 | 
| 3396 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3456 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 
| 3397   return TypeFeedbackVector::GetIndex(slot); | 3457   return TypeFeedbackVector::GetIndex(slot); | 
| 3398 } | 3458 } | 
| 3399 | 3459 | 
| 3400 }  // namespace interpreter | 3460 }  // namespace interpreter | 
| 3401 }  // namespace internal | 3461 }  // namespace internal | 
| 3402 }  // namespace v8 | 3462 }  // namespace v8 | 
| OLD | NEW | 
|---|