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

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.
neis 2016/09/02 12:06:07 This comment was not quite right: a scope may not
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();
neis 2016/09/02 12:06:07 I'm not happy with this name, as it can also creat
adamk 2016/09/02 17:51:51 BuildNewContext?
rmcilroy 2016/09/05 11:36:07 Could we do a rename pass on all the context creat
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
757 // In generator functions, we may not have visited every yield in the AST 756 // In generator functions, we may not have visited every yield in the AST
758 // since we skip some obviously dead code. Hence the generated bytecode may 757 // since we skip some obviously dead code. Hence the generated bytecode may
759 // contain jumps to unbound labels (resume points that will never be used). 758 // contain jumps to unbound labels (resume points that will never be used).
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 switch (variable->location()) { 949 switch (variable->location()) {
950 case VariableLocation::UNALLOCATED: { 950 case VariableLocation::UNALLOCATED: {
951 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); 951 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
952 globals_builder()->AddFunctionDeclaration(slot, decl->fun()); 952 globals_builder()->AddFunctionDeclaration(slot, decl->fun());
953 break; 953 break;
(...skipping 19 matching lines...) Expand all
973 Register name = register_allocator()->NextConsecutiveRegister(); 973 Register name = register_allocator()->NextConsecutiveRegister();
974 Register literal = register_allocator()->NextConsecutiveRegister(); 974 Register literal = register_allocator()->NextConsecutiveRegister();
975 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); 975 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name);
976 976
977 VisitForAccumulatorValue(decl->fun()); 977 VisitForAccumulatorValue(decl->fun());
978 builder()->StoreAccumulatorInRegister(literal).CallRuntime( 978 builder()->StoreAccumulatorInRegister(literal).CallRuntime(
979 Runtime::kDeclareEvalFunction, name, 2); 979 Runtime::kDeclareEvalFunction, name, 2);
980 break; 980 break;
981 } 981 }
982 case VariableLocation::MODULE: 982 case VariableLocation::MODULE:
983 UNREACHABLE(); 983 DCHECK(variable->mode() == LET);
984 VisitForAccumulatorValue(decl->fun());
985 VisitVariableAssignment(variable, Token::INIT,
986 FeedbackVectorSlot::Invalid());
987 break;
984 } 988 }
985 } 989 }
986 990
987 void BytecodeGenerator::VisitDeclarations( 991 void BytecodeGenerator::VisitDeclarations(
988 ZoneList<Declaration*>* declarations) { 992 ZoneList<Declaration*>* declarations) {
989 RegisterAllocationScope register_scope(this); 993 RegisterAllocationScope register_scope(this);
990 DCHECK(globals_builder()->empty()); 994 DCHECK(globals_builder()->empty());
991 for (int i = 0; i < declarations->length(); i++) { 995 for (int i = 0; i < declarations->length(); i++) {
992 RegisterAllocationScope register_scope(this); 996 RegisterAllocationScope register_scope(this);
993 Visit(declarations->at(i)); 997 Visit(declarations->at(i));
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 } 1983 }
1980 1984
1981 builder()->LoadContextSlot(context_reg, variable->index()); 1985 builder()->LoadContextSlot(context_reg, variable->index());
1982 BuildHoleCheckForVariableLoad(variable); 1986 BuildHoleCheckForVariableLoad(variable);
1983 break; 1987 break;
1984 } 1988 }
1985 case VariableLocation::LOOKUP: { 1989 case VariableLocation::LOOKUP: {
1986 builder()->LoadLookupSlot(variable->name(), typeof_mode); 1990 builder()->LoadLookupSlot(variable->name(), typeof_mode);
1987 break; 1991 break;
1988 } 1992 }
1989 case VariableLocation::MODULE: 1993 case VariableLocation::MODULE: {
1990 UNREACHABLE(); 1994 ModuleDescriptor* descriptor = scope()->GetModuleScope()->module();
1995 if (variable->IsExport()) {
1996 auto it = descriptor->regular_exports().find(variable->raw_name());
1997 DCHECK(it != descriptor->regular_exports().end());
1998 Register export_name = register_allocator()->NewRegister();
1999 builder()
2000 ->LoadLiteral(it->second->export_name->string())
2001 .StoreAccumulatorInRegister(export_name)
2002 .CallRuntime(Runtime::kLoadModuleExport, export_name, 1);
2003 } else {
2004 UNIMPLEMENTED();
2005 }
2006 break;
2007 }
1991 } 2008 }
1992 execution_result()->SetResultInAccumulator(); 2009 execution_result()->SetResultInAccumulator();
1993 } 2010 }
1994 2011
1995 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( 2012 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue(
1996 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { 2013 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
1997 AccumulatorResultScope accumulator_result(this); 2014 AccumulatorResultScope accumulator_result(this);
1998 VisitVariableLoad(variable, slot, typeof_mode); 2015 VisitVariableLoad(variable, slot, typeof_mode);
1999 } 2016 }
2000 2017
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2178 builder()->StoreContextSlot(context_reg, variable->index()); 2195 builder()->StoreContextSlot(context_reg, variable->index());
2179 } else if (variable->throw_on_const_assignment(language_mode())) { 2196 } else if (variable->throw_on_const_assignment(language_mode())) {
2180 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); 2197 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
2181 } 2198 }
2182 break; 2199 break;
2183 } 2200 }
2184 case VariableLocation::LOOKUP: { 2201 case VariableLocation::LOOKUP: {
2185 builder()->StoreLookupSlot(variable->name(), language_mode()); 2202 builder()->StoreLookupSlot(variable->name(), language_mode());
2186 break; 2203 break;
2187 } 2204 }
2188 case VariableLocation::MODULE: 2205 case VariableLocation::MODULE: {
2189 UNREACHABLE(); 2206 DCHECK(IsDeclaredVariableMode(mode));
2207
2208 if (mode == CONST && op != Token::INIT) {
2209 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
2210 break;
2211 }
2212
2213 // If we don't throw above, we know that we're dealing with an
2214 // export because imports are const and we do not generate initializing
2215 // assignments for them.
2216 DCHECK(variable->IsExport());
2217
2218 ModuleDescriptor* mod = scope()->GetModuleScope()->module();
2219 auto it = mod->regular_exports().find(variable->raw_name());
2220 DCHECK(it != mod->regular_exports().end());
2221
2222 register_allocator()->PrepareForConsecutiveAllocations(2);
2223 Register export_name = register_allocator()->NextConsecutiveRegister();
2224 Register value = register_allocator()->NextConsecutiveRegister();
2225 builder()
2226 ->StoreAccumulatorInRegister(value)
2227 .LoadLiteral(it->second->export_name->string())
2228 .StoreAccumulatorInRegister(export_name)
2229 .CallRuntime(Runtime::kStoreModuleExport, export_name, 2);
2230 break;
2231 }
2190 } 2232 }
2191 } 2233 }
2192 2234
2193 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 2235 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
2194 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); 2236 DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
2195 Register object, key, home_object, value; 2237 Register object, key, home_object, value;
2196 Handle<String> name; 2238 Handle<String> name;
2197 2239
2198 // Left-hand side can only be a property, a global or a variable slot. 2240 // Left-hand side can only be a property, a global or a variable slot.
2199 Property* property = expr->target()->AsProperty(); 2241 Property* property = expr->target()->AsProperty();
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
3136 } 3178 }
3137 3179
3138 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { 3180 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
3139 Visit(expr->expression()); 3181 Visit(expr->expression());
3140 } 3182 }
3141 3183
3142 void BytecodeGenerator::VisitNewLocalFunctionContext() { 3184 void BytecodeGenerator::VisitNewLocalFunctionContext() {
3143 AccumulatorResultScope accumulator_execution_result(this); 3185 AccumulatorResultScope accumulator_execution_result(this);
3144 Scope* scope = this->scope(); 3186 Scope* scope = this->scope();
3145 3187
3146 // Allocate a new local context. 3188 // Create the appropriate context.
3147 if (scope->is_script_scope()) { 3189 if (scope->is_module_scope()) {
3190 // We don't need to do anything for the outer script scope.
3191 DCHECK(scope->outer_scope()->is_script_scope());
3192
3193 RegisterAllocationScope register_scope(this);
3194 Register module = register_allocator()->NewRegister();
3195 Register closure = register_allocator()->NewRegister();
3196 Register scope_info = register_allocator()->NewRegister();
3197 DCHECK(Register::AreContiguous(module, closure, scope_info));
rmcilroy 2016/09/05 11:36:07 Please use PrepareForConsecutiveAllocations / Next
3198 // A JSFunction representing a module is called with the module object as
3199 // its sole argument, which we pass on to PushModuleContext.
3200 builder()
3201 ->MoveRegister(builder()->Parameter(1), module)
3202 .LoadAccumulatorWithRegister(Register::function_closure())
3203 .StoreAccumulatorInRegister(closure)
rmcilroy 2016/09/05 11:36:07 .MoveRegister(Register::function_closure(), closur
3204 .LoadLiteral(scope->scope_info())
3205 .StoreAccumulatorInRegister(scope_info)
3206 .CallRuntime(Runtime::kPushModuleContext, module, 3);
3207 } else if (scope->is_script_scope()) {
rmcilroy 2016/09/05 11:36:07 nit - could we do script scope first.
3148 RegisterAllocationScope register_scope(this); 3208 RegisterAllocationScope register_scope(this);
3149 Register closure = register_allocator()->NewRegister(); 3209 Register closure = register_allocator()->NewRegister();
3150 Register scope_info = register_allocator()->NewRegister(); 3210 Register scope_info = register_allocator()->NewRegister();
3151 DCHECK(Register::AreContiguous(closure, scope_info)); 3211 DCHECK(Register::AreContiguous(closure, scope_info));
3152 builder() 3212 builder()
3153 ->LoadAccumulatorWithRegister(Register::function_closure()) 3213 ->LoadAccumulatorWithRegister(Register::function_closure())
3154 .StoreAccumulatorInRegister(closure) 3214 .StoreAccumulatorInRegister(closure)
3155 .LoadLiteral(scope->scope_info()) 3215 .LoadLiteral(scope->scope_info())
3156 .StoreAccumulatorInRegister(scope_info) 3216 .StoreAccumulatorInRegister(scope_info)
3157 .CallRuntime(Runtime::kNewScriptContext, closure, 2); 3217 .CallRuntime(Runtime::kNewScriptContext, closure, 2);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3285 3345
3286 // Store the new target we were called with in the given variable. 3346 // Store the new target we were called with in the given variable.
3287 builder()->LoadAccumulatorWithRegister(Register::new_target()); 3347 builder()->LoadAccumulatorWithRegister(Register::new_target());
3288 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); 3348 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
3289 } 3349 }
3290 3350
3291 void BytecodeGenerator::VisitFunctionClosureForContext() { 3351 void BytecodeGenerator::VisitFunctionClosureForContext() {
3292 AccumulatorResultScope accumulator_execution_result(this); 3352 AccumulatorResultScope accumulator_execution_result(this);
3293 DeclarationScope* closure_scope = 3353 DeclarationScope* closure_scope =
3294 execution_context()->scope()->GetClosureScope(); 3354 execution_context()->scope()->GetClosureScope();
3295 if (closure_scope->is_script_scope() || 3355 if (closure_scope->is_script_scope()) {
3296 closure_scope->is_module_scope()) {
3297 // Contexts nested in the native context have a canonical empty function as 3356 // Contexts nested in the native context have a canonical empty function as
3298 // their closure, not the anonymous closure containing the global code. 3357 // their closure, not the anonymous closure containing the global code.
3299 Register native_context = register_allocator()->NewRegister(); 3358 Register native_context = register_allocator()->NewRegister();
3300 builder() 3359 builder()
3301 ->LoadContextSlot(execution_context()->reg(), 3360 ->LoadContextSlot(execution_context()->reg(),
3302 Context::NATIVE_CONTEXT_INDEX) 3361 Context::NATIVE_CONTEXT_INDEX)
3303 .StoreAccumulatorInRegister(native_context) 3362 .StoreAccumulatorInRegister(native_context)
3304 .LoadContextSlot(native_context, Context::CLOSURE_INDEX); 3363 .LoadContextSlot(native_context, Context::CLOSURE_INDEX);
3305 } else if (closure_scope->is_eval_scope()) { 3364 } else if (closure_scope->is_eval_scope()) {
3306 // Contexts created by a call to eval have the same closure as the 3365 // Contexts created by a call to eval have the same closure as the
3307 // context calling eval, not the anonymous closure containing the eval 3366 // context calling eval, not the anonymous closure containing the eval
3308 // code. Fetch it from the context. 3367 // code. Fetch it from the context.
3309 builder()->LoadContextSlot(execution_context()->reg(), 3368 builder()->LoadContextSlot(execution_context()->reg(),
3310 Context::CLOSURE_INDEX); 3369 Context::CLOSURE_INDEX);
3311 } else { 3370 } else {
3312 DCHECK(closure_scope->is_function_scope()); 3371 DCHECK(closure_scope->is_function_scope() ||
3372 closure_scope->is_module_scope());
3313 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 3373 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3314 } 3374 }
3315 execution_result()->SetResultInAccumulator(); 3375 execution_result()->SetResultInAccumulator();
3316 } 3376 }
3317 3377
3318 // Visits the expression |expr| and places the result in the accumulator. 3378 // Visits the expression |expr| and places the result in the accumulator.
3319 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { 3379 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
3320 AccumulatorResultScope accumulator_scope(this); 3380 AccumulatorResultScope accumulator_scope(this);
3321 Visit(expr); 3381 Visit(expr);
3322 } 3382 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3392 return execution_context()->scope()->language_mode(); 3452 return execution_context()->scope()->language_mode();
3393 } 3453 }
3394 3454
3395 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3455 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3396 return TypeFeedbackVector::GetIndex(slot); 3456 return TypeFeedbackVector::GetIndex(slot);
3397 } 3457 }
3398 3458
3399 } // namespace interpreter 3459 } // namespace interpreter
3400 } // namespace internal 3460 } // namespace internal
3401 } // namespace v8 3461 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698