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

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

Issue 2302783002: [modules] Basic support of exports (Closed)
Patch Set: Disable module tests for deopt fuzzer. 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
« no previous file with comments | « src/heap/heap.cc ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap/heap.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698