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

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

Issue 1425633002: [Interpreter] Add support for loading from / storing to outer context variables. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_conditional
Patch Set: Fix interpreter-assembler-unittests Created 5 years, 1 month 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/compiler/raw-machine-assembler.h ('k') | src/interpreter/interpreter.cc » ('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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/control-flow-builders.h" 8 #include "src/interpreter/control-flow-builders.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 25 matching lines...) Expand all
36 generator_->set_execution_context(this); 36 generator_->set_execution_context(this);
37 } 37 }
38 38
39 ~ContextScope() { 39 ~ContextScope() {
40 if (outer_ && should_pop_context_) { 40 if (outer_ && should_pop_context_) {
41 generator_->builder()->PopContext(outer_->reg()); 41 generator_->builder()->PopContext(outer_->reg());
42 } 42 }
43 generator_->set_execution_context(outer_); 43 generator_->set_execution_context(outer_);
44 } 44 }
45 45
46 // Returns the execution context for the given |scope| if it is a function 46 // Returns the depth of the given |scope| for the current execution context.
47 // local execution context, otherwise returns nullptr. 47 int ContextChainDepth(Scope* scope) {
48 ContextScope* Previous(Scope* scope) { 48 return scope_->ContextChainLength(scope);
49 int depth = scope_->ContextChainLength(scope); 49 }
50
51 // Returns the execution context at |depth| in the current context chain if it
52 // is a function local execution context, otherwise returns nullptr.
53 ContextScope* Previous(int depth) {
50 if (depth > depth_) { 54 if (depth > depth_) {
51 return nullptr; 55 return nullptr;
52 } 56 }
53 57
54 ContextScope* previous = this; 58 ContextScope* previous = this;
55 for (int i = depth; i > 0; --i) { 59 for (int i = depth; i > 0; --i) {
56 previous = previous->outer_; 60 previous = previous->outer_;
57 } 61 }
58 return previous; 62 return previous;
59 } 63 }
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 case VariableLocation::UNALLOCATED: { 411 case VariableLocation::UNALLOCATED: {
408 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( 412 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
409 decl->fun(), info()->script(), info()); 413 decl->fun(), info()->script(), info());
410 // Check for stack-overflow exception. 414 // Check for stack-overflow exception.
411 if (function.is_null()) return SetStackOverflow(); 415 if (function.is_null()) return SetStackOverflow();
412 globals()->push_back(variable->name()); 416 globals()->push_back(variable->name());
413 globals()->push_back(function); 417 globals()->push_back(function);
414 break; 418 break;
415 } 419 }
416 case VariableLocation::PARAMETER: 420 case VariableLocation::PARAMETER:
417 case VariableLocation::LOCAL: 421 case VariableLocation::LOCAL: {
418 case VariableLocation::CONTEXT: 422 VisitForAccumulatorValue(decl->fun());
423 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid());
424 break;
425 }
426 case VariableLocation::CONTEXT: {
427 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
428 VisitForAccumulatorValue(decl->fun());
429 builder()->StoreContextSlot(execution_context()->reg(),
430 variable->index());
431 break;
432 }
419 case VariableLocation::LOOKUP: 433 case VariableLocation::LOOKUP:
420 UNIMPLEMENTED(); 434 UNIMPLEMENTED();
421 } 435 }
422 } 436 }
423 437
424 438
425 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { 439 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
426 UNIMPLEMENTED(); 440 UNIMPLEMENTED();
427 } 441 }
428 442
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 break; 988 break;
975 } 989 }
976 case VariableLocation::GLOBAL: 990 case VariableLocation::GLOBAL:
977 case VariableLocation::UNALLOCATED: { 991 case VariableLocation::UNALLOCATED: {
978 size_t name_index = builder()->GetConstantPoolEntry(variable->name()); 992 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
979 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode()); 993 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode());
980 execution_result()->SetResultInAccumulator(); 994 execution_result()->SetResultInAccumulator();
981 break; 995 break;
982 } 996 }
983 case VariableLocation::CONTEXT: { 997 case VariableLocation::CONTEXT: {
984 ContextScope* context = execution_context()->Previous(variable->scope()); 998 int depth = execution_context()->ContextChainDepth(variable->scope());
999 ContextScope* context = execution_context()->Previous(depth);
1000 Register context_reg;
985 if (context) { 1001 if (context) {
986 builder()->LoadContextSlot(context->reg(), variable->index()); 1002 context_reg = context->reg();
987 execution_result()->SetResultInAccumulator();
988 } else { 1003 } else {
989 UNIMPLEMENTED(); 1004 context_reg = execution_result()->NewRegister();
1005 // Walk the context chain to find the context at the given depth.
1006 // TODO(rmcilroy): Perform this work in a bytecode handler once we have
1007 // a generic mechanism for performing jumps in interpreter.cc.
1008 builder()
1009 ->LoadAccumulatorWithRegister(execution_context()->reg())
1010 .StoreAccumulatorInRegister(context_reg);
1011 for (int i = 0; i < depth; ++i) {
1012 builder()
1013 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
1014 .StoreAccumulatorInRegister(context_reg);
1015 }
990 } 1016 }
1017 builder()->LoadContextSlot(context_reg, variable->index());
1018 execution_result()->SetResultInAccumulator();
991 // TODO(rmcilroy): Perform check for uninitialized legacy const, const and 1019 // TODO(rmcilroy): Perform check for uninitialized legacy const, const and
992 // let variables. 1020 // let variables.
993 break; 1021 break;
994 } 1022 }
995 case VariableLocation::LOOKUP: 1023 case VariableLocation::LOOKUP:
996 UNIMPLEMENTED(); 1024 UNIMPLEMENTED();
997 } 1025 }
998 } 1026 }
999 1027
1000 1028
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 break; 1060 break;
1033 } 1061 }
1034 case VariableLocation::GLOBAL: 1062 case VariableLocation::GLOBAL:
1035 case VariableLocation::UNALLOCATED: { 1063 case VariableLocation::UNALLOCATED: {
1036 size_t name_index = builder()->GetConstantPoolEntry(variable->name()); 1064 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
1037 builder()->StoreGlobal(name_index, feedback_index(slot), language_mode()); 1065 builder()->StoreGlobal(name_index, feedback_index(slot), language_mode());
1038 break; 1066 break;
1039 } 1067 }
1040 case VariableLocation::CONTEXT: { 1068 case VariableLocation::CONTEXT: {
1041 // TODO(rmcilroy): support const mode initialization. 1069 // TODO(rmcilroy): support const mode initialization.
1042 ContextScope* context = execution_context()->Previous(variable->scope()); 1070 int depth = execution_context()->ContextChainDepth(variable->scope());
1071 ContextScope* context = execution_context()->Previous(depth);
1072 Register context_reg;
1043 if (context) { 1073 if (context) {
1044 builder()->StoreContextSlot(context->reg(), variable->index()); 1074 context_reg = context->reg();
1045 } else { 1075 } else {
1046 UNIMPLEMENTED(); 1076 Register value_temp = execution_result()->NewRegister();
1077 context_reg = execution_result()->NewRegister();
1078 // Walk the context chain to find the context at the given depth.
1079 // TODO(rmcilroy): Perform this work in a bytecode handler once we have
1080 // a generic mechanism for performing jumps in interpreter.cc.
1081 builder()
1082 ->StoreAccumulatorInRegister(value_temp)
1083 .LoadAccumulatorWithRegister(execution_context()->reg())
1084 .StoreAccumulatorInRegister(context_reg);
1085 for (int i = 0; i < depth; ++i) {
1086 builder()
1087 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
1088 .StoreAccumulatorInRegister(context_reg);
1089 }
1090 builder()->LoadAccumulatorWithRegister(value_temp);
1047 } 1091 }
1092 builder()->StoreContextSlot(context_reg, variable->index());
1048 break; 1093 break;
1049 } 1094 }
1050 case VariableLocation::LOOKUP: 1095 case VariableLocation::LOOKUP:
1051 UNIMPLEMENTED(); 1096 UNIMPLEMENTED();
1052 } 1097 }
1053 } 1098 }
1054 1099
1055 1100
1056 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 1101 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
1057 DCHECK(expr->target()->IsValidReferenceExpression()); 1102 DCHECK(expr->target()->IsValidReferenceExpression());
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 } 1880 }
1836 1881
1837 1882
1838 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 1883 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1839 return info()->feedback_vector()->GetIndex(slot); 1884 return info()->feedback_vector()->GetIndex(slot);
1840 } 1885 }
1841 1886
1842 } // namespace interpreter 1887 } // namespace interpreter
1843 } // namespace internal 1888 } // namespace internal
1844 } // namespace v8 1889 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/raw-machine-assembler.h ('k') | src/interpreter/interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698