Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2302783002: [modules] Basic support of exports (Closed)
Patch Set: . Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 933
935 Register name = register_allocator()->NewRegister(); 934 Register name = register_allocator()->NewRegister();
936 935
937 builder() 936 builder()
938 ->LoadLiteral(variable->name()) 937 ->LoadLiteral(variable->name())
939 .StoreAccumulatorInRegister(name) 938 .StoreAccumulatorInRegister(name)
940 .CallRuntime(Runtime::kDeclareEvalVar, name, 1); 939 .CallRuntime(Runtime::kDeclareEvalVar, name, 1);
941 break; 940 break;
942 } 941 }
943 case VariableLocation::MODULE: 942 case VariableLocation::MODULE:
944 UNREACHABLE(); 943 // Nothing to do here.
944 break;
945 } 945 }
946 } 946 }
947 947
948 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { 948 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
949 Variable* variable = decl->proxy()->var(); 949 Variable* variable = decl->proxy()->var();
950 switch (variable->location()) { 950 switch (variable->location()) {
951 case VariableLocation::GLOBAL: 951 case VariableLocation::GLOBAL:
952 case VariableLocation::UNALLOCATED: { 952 case VariableLocation::UNALLOCATED: {
953 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); 953 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
954 globals_builder()->AddFunctionDeclaration(slot, decl->fun()); 954 globals_builder()->AddFunctionDeclaration(slot, decl->fun());
955 break; 955 break;
956 } 956 }
957 case VariableLocation::PARAMETER: 957 case VariableLocation::PARAMETER:
958 case VariableLocation::LOCAL: { 958 case VariableLocation::LOCAL: {
959 VisitForAccumulatorValue(decl->fun()); 959 VisitForAccumulatorValue(decl->fun());
960 DCHECK(variable->mode() == LET || variable->mode() == VAR || 960 DCHECK(variable->mode() == LET || variable->mode() == VAR ||
961 variable->mode() == CONST); 961 variable->mode() == CONST);
adamk 2016/09/01 23:13:34 I think you already touched this DCHECK in a diffe
neis 2016/09/02 11:32:58 Done in the other CL.
962 VisitVariableAssignment(variable, Token::INIT, 962 VisitVariableAssignment(variable, Token::INIT,
963 FeedbackVectorSlot::Invalid()); 963 FeedbackVectorSlot::Invalid());
964 break; 964 break;
965 } 965 }
966 case VariableLocation::CONTEXT: { 966 case VariableLocation::CONTEXT: {
967 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); 967 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
968 VisitForAccumulatorValue(decl->fun()); 968 VisitForAccumulatorValue(decl->fun());
969 builder()->StoreContextSlot(execution_context()->reg(), 969 builder()->StoreContextSlot(execution_context()->reg(),
970 variable->index()); 970 variable->index());
971 break; 971 break;
972 } 972 }
973 case VariableLocation::LOOKUP: { 973 case VariableLocation::LOOKUP: {
974 register_allocator()->PrepareForConsecutiveAllocations(2); 974 register_allocator()->PrepareForConsecutiveAllocations(2);
975 Register name = register_allocator()->NextConsecutiveRegister(); 975 Register name = register_allocator()->NextConsecutiveRegister();
976 Register literal = register_allocator()->NextConsecutiveRegister(); 976 Register literal = register_allocator()->NextConsecutiveRegister();
977 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); 977 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name);
978 978
979 VisitForAccumulatorValue(decl->fun()); 979 VisitForAccumulatorValue(decl->fun());
980 builder()->StoreAccumulatorInRegister(literal).CallRuntime( 980 builder()->StoreAccumulatorInRegister(literal).CallRuntime(
981 Runtime::kDeclareEvalFunction, name, 2); 981 Runtime::kDeclareEvalFunction, name, 2);
982 break; 982 break;
983 } 983 }
984 case VariableLocation::MODULE: 984 case VariableLocation::MODULE:
985 UNREACHABLE(); 985 VisitForAccumulatorValue(decl->fun());
adamk 2016/09/01 23:13:34 Add a DCHECK above here that the mode is LET?
neis 2016/09/02 11:32:58 Done.
986 VisitVariableAssignment(variable, Token::INIT,
987 FeedbackVectorSlot::Invalid());
988 break;
986 } 989 }
987 } 990 }
988 991
989 void BytecodeGenerator::VisitDeclarations( 992 void BytecodeGenerator::VisitDeclarations(
990 ZoneList<Declaration*>* declarations) { 993 ZoneList<Declaration*>* declarations) {
991 RegisterAllocationScope register_scope(this); 994 RegisterAllocationScope register_scope(this);
992 DCHECK(globals_builder()->empty()); 995 DCHECK(globals_builder()->empty());
993 for (int i = 0; i < declarations->length(); i++) { 996 for (int i = 0; i < declarations->length(); i++) {
994 RegisterAllocationScope register_scope(this); 997 RegisterAllocationScope register_scope(this);
995 Visit(declarations->at(i)); 998 Visit(declarations->at(i));
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 } 1985 }
1983 1986
1984 builder()->LoadContextSlot(context_reg, variable->index()); 1987 builder()->LoadContextSlot(context_reg, variable->index());
1985 BuildHoleCheckForVariableLoad(variable); 1988 BuildHoleCheckForVariableLoad(variable);
1986 break; 1989 break;
1987 } 1990 }
1988 case VariableLocation::LOOKUP: { 1991 case VariableLocation::LOOKUP: {
1989 builder()->LoadLookupSlot(variable->name(), typeof_mode); 1992 builder()->LoadLookupSlot(variable->name(), typeof_mode);
1990 break; 1993 break;
1991 } 1994 }
1992 case VariableLocation::MODULE: 1995 case VariableLocation::MODULE: {
1993 UNREACHABLE(); 1996 ModuleDescriptor* descriptor = scope()->GetModuleScope()->module();
1997 if (variable->IsExport()) {
1998 auto it = descriptor->regular_exports().find(variable->raw_name());
1999 DCHECK(it != descriptor->regular_exports().end());
2000 Register export_name = register_allocator()->NewRegister();
2001 builder()
2002 ->LoadLiteral(it->second->export_name->string())
2003 .StoreAccumulatorInRegister(export_name)
2004 .CallRuntime(Runtime::kLoadModuleExport, export_name, 1);
2005 } else {
2006 UNIMPLEMENTED();
2007 }
2008 break;
2009 }
1994 } 2010 }
1995 execution_result()->SetResultInAccumulator(); 2011 execution_result()->SetResultInAccumulator();
1996 } 2012 }
1997 2013
1998 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( 2014 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue(
1999 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { 2015 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
2000 AccumulatorResultScope accumulator_result(this); 2016 AccumulatorResultScope accumulator_result(this);
2001 VisitVariableLoad(variable, slot, typeof_mode); 2017 VisitVariableLoad(variable, slot, typeof_mode);
2002 } 2018 }
2003 2019
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2182 builder()->StoreContextSlot(context_reg, variable->index()); 2198 builder()->StoreContextSlot(context_reg, variable->index());
2183 } else if (variable->throw_on_const_assignment(language_mode())) { 2199 } else if (variable->throw_on_const_assignment(language_mode())) {
2184 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); 2200 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
2185 } 2201 }
2186 break; 2202 break;
2187 } 2203 }
2188 case VariableLocation::LOOKUP: { 2204 case VariableLocation::LOOKUP: {
2189 builder()->StoreLookupSlot(variable->name(), language_mode()); 2205 builder()->StoreLookupSlot(variable->name(), language_mode());
2190 break; 2206 break;
2191 } 2207 }
2192 case VariableLocation::MODULE: 2208 case VariableLocation::MODULE: {
2193 UNREACHABLE(); 2209 DCHECK(IsDeclaredVariableMode(mode));
2210
2211 if (mode == CONST && op != Token::INIT) {
2212 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
2213 break;
2214 }
2215
2216 // If we don't throw above, we know that we're dealing with an
2217 // export because imports are const and we do not generate initializing
2218 // assignments for them.
2219 DCHECK(variable->IsExport());
2220
2221 ModuleDescriptor* mod = scope()->GetModuleScope()->module();
2222 auto it = mod->regular_exports().find(variable->raw_name());
2223 DCHECK(it != mod->regular_exports().end());
2224
2225 register_allocator()->PrepareForConsecutiveAllocations(2);
2226 Register export_name = register_allocator()->NextConsecutiveRegister();
2227 Register value = register_allocator()->NextConsecutiveRegister();
2228 builder()
2229 ->StoreAccumulatorInRegister(value)
2230 .LoadLiteral(it->second->export_name->string())
2231 .StoreAccumulatorInRegister(export_name)
2232 .CallRuntime(Runtime::kStoreModuleExport, export_name, 2);
2233 break;
2234 }
2194 } 2235 }
2195 } 2236 }
2196 2237
2197 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 2238 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
2198 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); 2239 DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
2199 Register object, key, home_object, value; 2240 Register object, key, home_object, value;
2200 Handle<String> name; 2241 Handle<String> name;
2201 2242
2202 // Left-hand side can only be a property, a global or a variable slot. 2243 // Left-hand side can only be a property, a global or a variable slot.
2203 Property* property = expr->target()->AsProperty(); 2244 Property* property = expr->target()->AsProperty();
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
3134 } 3175 }
3135 3176
3136 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { 3177 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
3137 Visit(expr->expression()); 3178 Visit(expr->expression());
3138 } 3179 }
3139 3180
3140 void BytecodeGenerator::VisitNewLocalFunctionContext() { 3181 void BytecodeGenerator::VisitNewLocalFunctionContext() {
3141 AccumulatorResultScope accumulator_execution_result(this); 3182 AccumulatorResultScope accumulator_execution_result(this);
3142 Scope* scope = this->scope(); 3183 Scope* scope = this->scope();
3143 3184
3144 // Allocate a new local context. 3185 // Allocate a new local context. XXX
3145 if (scope->is_script_scope()) { 3186 if (scope->is_module_scope()) {
3187 // We don't need to do anything for the outer script scope.
3188 DCHECK(scope->outer_scope()->is_script_scope());
3189
3190 RegisterAllocationScope register_scope(this);
3191 Register module = register_allocator()->NewRegister();
3192 Register closure = register_allocator()->NewRegister();
3193 Register scope_info = register_allocator()->NewRegister();
3194 DCHECK(Register::AreContiguous(module, closure, scope_info));
3195 // A JSFunction representing a module is called with the module object as
3196 // its sole argument, which we pass on to PushModuleContext.
3197 builder()
3198 ->MoveRegister(builder()->Parameter(1), module)
3199 .LoadAccumulatorWithRegister(Register::function_closure())
3200 .StoreAccumulatorInRegister(closure)
3201 .LoadLiteral(scope->scope_info())
3202 .StoreAccumulatorInRegister(scope_info)
3203 .CallRuntime(Runtime::kPushModuleContext, module, 3);
3204 } else if (scope->is_script_scope()) {
3146 RegisterAllocationScope register_scope(this); 3205 RegisterAllocationScope register_scope(this);
3147 Register closure = register_allocator()->NewRegister(); 3206 Register closure = register_allocator()->NewRegister();
3148 Register scope_info = register_allocator()->NewRegister(); 3207 Register scope_info = register_allocator()->NewRegister();
3149 DCHECK(Register::AreContiguous(closure, scope_info)); 3208 DCHECK(Register::AreContiguous(closure, scope_info));
3150 builder() 3209 builder()
3151 ->LoadAccumulatorWithRegister(Register::function_closure()) 3210 ->LoadAccumulatorWithRegister(Register::function_closure())
3152 .StoreAccumulatorInRegister(closure) 3211 .StoreAccumulatorInRegister(closure)
3153 .LoadLiteral(scope->scope_info()) 3212 .LoadLiteral(scope->scope_info())
3154 .StoreAccumulatorInRegister(scope_info) 3213 .StoreAccumulatorInRegister(scope_info)
3155 .CallRuntime(Runtime::kNewScriptContext, closure, 2); 3214 .CallRuntime(Runtime::kNewScriptContext, closure, 2);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3283 3342
3284 // Store the new target we were called with in the given variable. 3343 // Store the new target we were called with in the given variable.
3285 builder()->LoadAccumulatorWithRegister(Register::new_target()); 3344 builder()->LoadAccumulatorWithRegister(Register::new_target());
3286 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); 3345 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
3287 } 3346 }
3288 3347
3289 void BytecodeGenerator::VisitFunctionClosureForContext() { 3348 void BytecodeGenerator::VisitFunctionClosureForContext() {
3290 AccumulatorResultScope accumulator_execution_result(this); 3349 AccumulatorResultScope accumulator_execution_result(this);
3291 DeclarationScope* closure_scope = 3350 DeclarationScope* closure_scope =
3292 execution_context()->scope()->GetClosureScope(); 3351 execution_context()->scope()->GetClosureScope();
3293 if (closure_scope->is_script_scope() || 3352 if (closure_scope->is_script_scope()) {
3294 closure_scope->is_module_scope()) {
3295 // Contexts nested in the native context have a canonical empty function as 3353 // Contexts nested in the native context have a canonical empty function as
3296 // their closure, not the anonymous closure containing the global code. 3354 // their closure, not the anonymous closure containing the global code.
3297 Register native_context = register_allocator()->NewRegister(); 3355 Register native_context = register_allocator()->NewRegister();
3298 builder() 3356 builder()
3299 ->LoadContextSlot(execution_context()->reg(), 3357 ->LoadContextSlot(execution_context()->reg(),
3300 Context::NATIVE_CONTEXT_INDEX) 3358 Context::NATIVE_CONTEXT_INDEX)
3301 .StoreAccumulatorInRegister(native_context) 3359 .StoreAccumulatorInRegister(native_context)
3302 .LoadContextSlot(native_context, Context::CLOSURE_INDEX); 3360 .LoadContextSlot(native_context, Context::CLOSURE_INDEX);
3303 } else if (closure_scope->is_eval_scope()) { 3361 } else if (closure_scope->is_eval_scope()) {
3304 // Contexts created by a call to eval have the same closure as the 3362 // Contexts created by a call to eval have the same closure as the
3305 // context calling eval, not the anonymous closure containing the eval 3363 // context calling eval, not the anonymous closure containing the eval
3306 // code. Fetch it from the context. 3364 // code. Fetch it from the context.
3307 builder()->LoadContextSlot(execution_context()->reg(), 3365 builder()->LoadContextSlot(execution_context()->reg(),
3308 Context::CLOSURE_INDEX); 3366 Context::CLOSURE_INDEX);
3309 } else { 3367 } else {
3310 DCHECK(closure_scope->is_function_scope()); 3368 DCHECK(closure_scope->is_function_scope() ||
3369 closure_scope->is_module_scope());
3311 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 3370 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3312 } 3371 }
3313 execution_result()->SetResultInAccumulator(); 3372 execution_result()->SetResultInAccumulator();
3314 } 3373 }
3315 3374
3316 // Visits the expression |expr| and places the result in the accumulator. 3375 // Visits the expression |expr| and places the result in the accumulator.
3317 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { 3376 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
3318 AccumulatorResultScope accumulator_scope(this); 3377 AccumulatorResultScope accumulator_scope(this);
3319 Visit(expr); 3378 Visit(expr);
3320 } 3379 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3390 return execution_context()->scope()->language_mode(); 3449 return execution_context()->scope()->language_mode();
3391 } 3450 }
3392 3451
3393 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3452 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3394 return TypeFeedbackVector::GetIndex(slot); 3453 return TypeFeedbackVector::GetIndex(slot);
3395 } 3454 }
3396 3455
3397 } // namespace interpreter 3456 } // namespace interpreter
3398 } // namespace internal 3457 } // namespace internal
3399 } // namespace v8 3458 } // namespace v8
OLDNEW
« src/factory.cc ('K') | « src/heap/heap.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698