Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <map> | 5 #include <map> |
| 6 #include <set> | 6 #include <set> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "vm/kernel_to_il.h" | 9 #include "vm/kernel_to_il.h" |
| 10 | 10 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 } else if ((*outermost_node)->IsConstructor()) { | 51 } else if ((*outermost_node)->IsConstructor()) { |
| 52 parent = Constructor::Cast(*outermost_node)->parent(); | 52 parent = Constructor::Cast(*outermost_node)->parent(); |
| 53 } else if ((*outermost_node)->IsField()) { | 53 } else if ((*outermost_node)->IsField()) { |
| 54 parent = Field::Cast(*outermost_node)->parent(); | 54 parent = Field::Cast(*outermost_node)->parent(); |
| 55 } | 55 } |
| 56 if (parent != NULL && parent->IsClass()) *klass = Class::Cast(parent); | 56 if (parent != NULL && parent->IsClass()) *klass = Class::Cast(parent); |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 | 59 |
| 60 | 60 |
| 61 void ScopeBuilder::EnterScope(TreeNode* node, TokenPosition start_position) { | 61 template <typename NewScopeType> |
| 62 void ScopeBuilder::EnterScope(NewScopeType* node, | |
|
Kevin Millikin (Google)
2017/03/28 06:42:23
Instead of the template functions I'd rather add o
jensj
2017/03/28 08:56:28
Done.
| |
| 63 TokenPosition start_position) { | |
| 62 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); | 64 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); |
| 63 scope_->set_begin_token_pos(start_position); | 65 scope_->set_begin_token_pos(start_position); |
| 64 result_->scopes.Insert(node, scope_); | 66 result_->scopes.Insert(node->kernel_file_offset(), scope_); |
| 65 } | 67 } |
| 66 | 68 |
| 67 | 69 |
| 68 void ScopeBuilder::ExitScope(TokenPosition end_position) { | 70 void ScopeBuilder::ExitScope(TokenPosition end_position) { |
| 69 scope_->set_end_token_pos(end_position); | 71 scope_->set_end_token_pos(end_position); |
| 70 scope_ = scope_->parent(); | 72 scope_ = scope_->parent(); |
| 71 } | 73 } |
| 72 | 74 |
| 73 | 75 |
| 74 LocalVariable* ScopeBuilder::MakeVariable(TokenPosition declaration_pos, | 76 LocalVariable* ScopeBuilder::MakeVariable(TokenPosition declaration_pos, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 93 | 95 |
| 94 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, | 96 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, |
| 95 intptr_t pos) { | 97 intptr_t pos) { |
| 96 LocalVariable* variable = MakeVariable( | 98 LocalVariable* variable = MakeVariable( |
| 97 declaration->position(), declaration->position(), | 99 declaration->position(), declaration->position(), |
| 98 H.DartSymbol(declaration->name()), T.TranslateVariableType(declaration)); | 100 H.DartSymbol(declaration->name()), T.TranslateVariableType(declaration)); |
| 99 if (declaration->IsFinal()) { | 101 if (declaration->IsFinal()) { |
| 100 variable->set_is_final(); | 102 variable->set_is_final(); |
| 101 } | 103 } |
| 102 scope_->InsertParameterAt(pos, variable); | 104 scope_->InsertParameterAt(pos, variable); |
| 103 result_->locals.Insert(declaration, variable); | 105 result_->locals.Insert(declaration->kernel_file_offset(), variable); |
| 104 | 106 |
| 105 // The default value may contain 'let' bindings for which the constant | 107 // The default value may contain 'let' bindings for which the constant |
| 106 // evaluator needs scope bindings. | 108 // evaluator needs scope bindings. |
| 107 Expression* defaultValue = declaration->initializer(); | 109 Expression* defaultValue = declaration->initializer(); |
| 108 if (defaultValue != NULL) { | 110 if (defaultValue != NULL) { |
| 109 defaultValue->AcceptExpressionVisitor(this); | 111 defaultValue->AcceptExpressionVisitor(this); |
| 110 } | 112 } |
| 111 } | 113 } |
| 112 | 114 |
| 113 | 115 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 LocalVariable* iterator = | 180 LocalVariable* iterator = |
| 179 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 181 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 180 GenerateName(":iterator", depth_.for_in_ - 1), | 182 GenerateName(":iterator", depth_.for_in_ - 1), |
| 181 AbstractType::dynamic_type()); | 183 AbstractType::dynamic_type()); |
| 182 current_function_scope_->AddVariable(iterator); | 184 current_function_scope_->AddVariable(iterator); |
| 183 result_->iterator_variables.Add(iterator); | 185 result_->iterator_variables.Add(iterator); |
| 184 } | 186 } |
| 185 | 187 |
| 186 | 188 |
| 187 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { | 189 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { |
| 188 LocalVariable* variable = result_->locals.Lookup(declaration); | 190 LocalVariable* variable = |
| 191 result_->locals.Lookup(declaration->kernel_file_offset()); | |
| 189 if (variable == NULL) { | 192 if (variable == NULL) { |
| 190 // We have not seen a declaration of the variable, so it must be the | 193 // We have not seen a declaration of the variable, so it must be the |
| 191 // case that we are compiling a nested function and the variable is | 194 // case that we are compiling a nested function and the variable is |
| 192 // declared in an outer scope. In that case, look it up in the scope by | 195 // declared in an outer scope. In that case, look it up in the scope by |
| 193 // name and add it to the variable map to simplify later lookup. | 196 // name and add it to the variable map to simplify later lookup. |
| 194 ASSERT(current_function_scope_->parent() != NULL); | 197 ASSERT(current_function_scope_->parent() != NULL); |
| 195 const dart::String& name = H.DartSymbol(declaration->name()); | 198 const dart::String& name = H.DartSymbol(declaration->name()); |
| 196 variable = current_function_scope_->parent()->LookupVariable(name, true); | 199 variable = current_function_scope_->parent()->LookupVariable(name, true); |
| 197 ASSERT(variable != NULL); | 200 ASSERT(variable != NULL); |
| 198 result_->locals.Insert(declaration, variable); | 201 result_->locals.Insert(declaration->kernel_file_offset(), variable); |
| 199 } | 202 } |
| 200 if (variable->owner()->function_level() < scope_->function_level()) { | 203 if (variable->owner()->function_level() < scope_->function_level()) { |
| 201 // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two | 204 // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two |
| 202 // different reasons: | 205 // different reasons: |
| 203 // Scenario 1: | 206 // Scenario 1: |
| 204 // We need to know which variables defined in this function | 207 // We need to know which variables defined in this function |
| 205 // are closed over by nested closures in order to ensure we will | 208 // are closed over by nested closures in order to ensure we will |
| 206 // create a [Context] object of appropriate size and store captured | 209 // create a [Context] object of appropriate size and store captured |
| 207 // variables there instead of the stack. | 210 // variables there instead of the stack. |
| 208 // Scenario 2: | 211 // Scenario 2: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 const dart::String& name = declaration->name()->is_empty() | 245 const dart::String& name = declaration->name()->is_empty() |
| 243 ? GenerateName(":var", name_index_++) | 246 ? GenerateName(":var", name_index_++) |
| 244 : H.DartSymbol(declaration->name()); | 247 : H.DartSymbol(declaration->name()); |
| 245 LocalVariable* variable = | 248 LocalVariable* variable = |
| 246 MakeVariable(declaration->position(), declaration->end_position(), name, | 249 MakeVariable(declaration->position(), declaration->end_position(), name, |
| 247 T.TranslateVariableType(declaration)); | 250 T.TranslateVariableType(declaration)); |
| 248 if (declaration->IsFinal()) { | 251 if (declaration->IsFinal()) { |
| 249 variable->set_is_final(); | 252 variable->set_is_final(); |
| 250 } | 253 } |
| 251 scope_->AddVariable(variable); | 254 scope_->AddVariable(variable); |
| 252 result_->locals.Insert(declaration, variable); | 255 result_->locals.Insert(declaration->kernel_file_offset(), variable); |
| 253 } | 256 } |
| 254 | 257 |
| 255 | 258 |
| 256 static bool IsStaticInitializer(const Function& function, Zone* zone) { | 259 static bool IsStaticInitializer(const Function& function, Zone* zone) { |
| 257 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && | 260 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && |
| 258 dart::String::Handle(zone, function.name()) | 261 dart::String::Handle(zone, function.name()) |
| 259 .StartsWith(Symbols::InitPrefix()); | 262 .StartsWith(Symbols::InitPrefix()); |
| 260 } | 263 } |
| 261 | 264 |
| 262 | 265 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 LookupVariable(node->variable()); | 478 LookupVariable(node->variable()); |
| 476 } | 479 } |
| 477 | 480 |
| 478 | 481 |
| 479 void ScopeBuilder::VisitVariableSet(VariableSet* node) { | 482 void ScopeBuilder::VisitVariableSet(VariableSet* node) { |
| 480 LookupVariable(node->variable()); | 483 LookupVariable(node->variable()); |
| 481 node->VisitChildren(this); | 484 node->VisitChildren(this); |
| 482 } | 485 } |
| 483 | 486 |
| 484 | 487 |
| 485 void ScopeBuilder::HandleLocalFunction(TreeNode* parent, | 488 template <typename FunctionType> |
| 489 void ScopeBuilder::HandleLocalFunction(FunctionType* parent, | |
| 486 FunctionNode* function) { | 490 FunctionNode* function) { |
| 487 LocalScope* saved_function_scope = current_function_scope_; | 491 LocalScope* saved_function_scope = current_function_scope_; |
| 488 FunctionNode* saved_function_node = current_function_node_; | 492 FunctionNode* saved_function_node = current_function_node_; |
| 489 ScopeBuilder::DepthState saved_depth_state = depth_; | 493 ScopeBuilder::DepthState saved_depth_state = depth_; |
| 490 depth_ = DepthState(depth_.function_ + 1); | 494 depth_ = DepthState(depth_.function_ + 1); |
| 491 EnterScope(parent, function->position()); | 495 EnterScope(parent, function->position()); |
| 492 current_function_scope_ = scope_; | 496 current_function_scope_ = scope_; |
| 493 current_function_node_ = function; | 497 current_function_node_ = function; |
| 494 if (depth_.function_ == 1) { | 498 if (depth_.function_ == 1) { |
| 495 FunctionScope function_scope = {function, scope_}; | 499 FunctionScope function_scope = {function->kernel_file_offset(), scope_}; |
| 496 result_->function_scopes.Add(function_scope); | 500 result_->function_scopes.Add(function_scope); |
| 497 } | 501 } |
| 498 AddParameters(function); | 502 AddParameters(function); |
| 499 VisitFunctionNode(function); | 503 VisitFunctionNode(function); |
| 500 ExitScope(function->end_position()); | 504 ExitScope(function->end_position()); |
| 501 depth_ = saved_depth_state; | 505 depth_ = saved_depth_state; |
| 502 current_function_scope_ = saved_function_scope; | 506 current_function_scope_ = saved_function_scope; |
| 503 current_function_node_ = saved_function_node; | 507 current_function_node_ = saved_function_node; |
| 504 } | 508 } |
| 505 | 509 |
| (...skipping 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2003 | 2007 |
| 2004 try_finally_block_ = saved_block; | 2008 try_finally_block_ = saved_block; |
| 2005 try_catch_block_ = saved_try_catch_block; | 2009 try_catch_block_ = saved_try_catch_block; |
| 2006 context_depth_ = saved_depth; | 2010 context_depth_ = saved_depth; |
| 2007 try_depth_ = saved_try_depth; | 2011 try_depth_ = saved_try_depth; |
| 2008 | 2012 |
| 2009 return instructions; | 2013 return instructions; |
| 2010 } | 2014 } |
| 2011 | 2015 |
| 2012 | 2016 |
| 2013 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { | 2017 Fragment FlowGraphBuilder::EnterScope(int64_t kernel_offset, |
|
Kevin Millikin (Google)
2017/03/28 06:42:22
It's a little confusing that this is sometimes 'ke
jensj
2017/03/28 08:56:28
Done.
| |
| 2018 bool* new_context) { | |
| 2014 Fragment instructions; | 2019 Fragment instructions; |
| 2015 const intptr_t context_size = | 2020 const intptr_t context_size = |
| 2016 scopes_->scopes.Lookup(node)->num_context_variables(); | 2021 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); |
| 2017 if (context_size > 0) { | 2022 if (context_size > 0) { |
| 2018 instructions += PushContext(context_size); | 2023 instructions += PushContext(context_size); |
| 2019 instructions += Drop(); | 2024 instructions += Drop(); |
| 2020 if (new_context != NULL) { | 2025 if (new_context != NULL) { |
| 2021 *new_context = true; | 2026 *new_context = true; |
| 2022 } | 2027 } |
| 2023 } | 2028 } |
| 2024 return instructions; | 2029 return instructions; |
| 2025 } | 2030 } |
| 2026 | 2031 |
| 2027 | 2032 |
| 2028 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) { | 2033 Fragment FlowGraphBuilder::ExitScope(int64_t kernel_offset) { |
| 2029 Fragment instructions; | 2034 Fragment instructions; |
| 2030 const intptr_t context_size = | 2035 const intptr_t context_size = |
| 2031 scopes_->scopes.Lookup(node)->num_context_variables(); | 2036 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); |
| 2032 if (context_size > 0) { | 2037 if (context_size > 0) { |
| 2033 instructions += PopContext(); | 2038 instructions += PopContext(); |
| 2034 } | 2039 } |
| 2035 return instructions; | 2040 return instructions; |
| 2036 } | 2041 } |
| 2037 | 2042 |
| 2038 | 2043 |
| 2039 Fragment FlowGraphBuilder::LoadContextAt(int depth) { | 2044 Fragment FlowGraphBuilder::LoadContextAt(int depth) { |
| 2040 intptr_t delta = context_depth_ - depth; | 2045 intptr_t delta = context_depth_ - depth; |
| 2041 ASSERT(delta >= 0); | 2046 ASSERT(delta >= 0); |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2874 if (try_catch_block_ == NULL) { | 2879 if (try_catch_block_ == NULL) { |
| 2875 return CatchClauseNode::kInvalidTryIndex; | 2880 return CatchClauseNode::kInvalidTryIndex; |
| 2876 } else { | 2881 } else { |
| 2877 return try_catch_block_->try_index(); | 2882 return try_catch_block_->try_index(); |
| 2878 } | 2883 } |
| 2879 } | 2884 } |
| 2880 | 2885 |
| 2881 | 2886 |
| 2882 dart::LocalVariable* FlowGraphBuilder::LookupVariable( | 2887 dart::LocalVariable* FlowGraphBuilder::LookupVariable( |
| 2883 VariableDeclaration* var) { | 2888 VariableDeclaration* var) { |
| 2884 LocalVariable* local = scopes_->locals.Lookup(var); | 2889 LocalVariable* local = scopes_->locals.Lookup(var->kernel_file_offset()); |
| 2885 ASSERT(local != NULL); | 2890 ASSERT(local != NULL); |
| 2886 return local; | 2891 return local; |
| 2887 } | 2892 } |
| 2888 | 2893 |
| 2889 | 2894 |
| 2890 void FlowGraphBuilder::SetTempIndex(Definition* definition) { | 2895 void FlowGraphBuilder::SetTempIndex(Definition* definition) { |
| 2891 definition->set_temp_index( | 2896 definition->set_temp_index( |
| 2892 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); | 2897 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); |
| 2893 } | 2898 } |
| 2894 | 2899 |
| (...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4079 // class A { | 4084 // class A { |
| 4080 // var x = (expr); | 4085 // var x = (expr); |
| 4081 // } | 4086 // } |
| 4082 for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) { | 4087 for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) { |
| 4083 Field* kernel_field = kernel_klass->fields()[i]; | 4088 Field* kernel_field = kernel_klass->fields()[i]; |
| 4084 Expression* init = kernel_field->initializer(); | 4089 Expression* init = kernel_field->initializer(); |
| 4085 if (!kernel_field->IsStatic() && init != NULL) { | 4090 if (!kernel_field->IsStatic() && init != NULL) { |
| 4086 dart::Field& field = | 4091 dart::Field& field = |
| 4087 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); | 4092 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field)); |
| 4088 | 4093 |
| 4089 EnterScope(kernel_field); | 4094 EnterScope(kernel_field->kernel_file_offset()); |
| 4090 instructions += LoadLocal(scopes_->this_variable); | 4095 instructions += LoadLocal(scopes_->this_variable); |
| 4091 instructions += TranslateExpression(init); | 4096 instructions += TranslateExpression(init); |
| 4092 instructions += StoreInstanceFieldGuarded(field, true); | 4097 instructions += StoreInstanceFieldGuarded(field, true); |
| 4093 ExitScope(kernel_field); | 4098 ExitScope(kernel_field->kernel_file_offset()); |
| 4094 } | 4099 } |
| 4095 } | 4100 } |
| 4096 | 4101 |
| 4097 // These to come from: | 4102 // These to come from: |
| 4098 // class A { | 4103 // class A { |
| 4099 // var x; | 4104 // var x; |
| 4100 // var y; | 4105 // var y; |
| 4101 // A(this.x) : super(expr), y = (expr); | 4106 // A(this.x) : super(expr), y = (expr); |
| 4102 // } | 4107 // } |
| 4103 for (intptr_t i = 0; i < initializers->length(); i++) { | 4108 for (intptr_t i = 0; i < initializers->length(); i++) { |
| (...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5368 | 5373 |
| 5369 | 5374 |
| 5370 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) { | 5375 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) { |
| 5371 fragment_ = Fragment(); | 5376 fragment_ = Fragment(); |
| 5372 } | 5377 } |
| 5373 | 5378 |
| 5374 | 5379 |
| 5375 void FlowGraphBuilder::VisitBlock(Block* node) { | 5380 void FlowGraphBuilder::VisitBlock(Block* node) { |
| 5376 Fragment instructions; | 5381 Fragment instructions; |
| 5377 | 5382 |
| 5378 instructions += EnterScope(node); | 5383 instructions += EnterScope(node->kernel_file_offset()); |
| 5379 List<Statement>& statements = node->statements(); | 5384 List<Statement>& statements = node->statements(); |
| 5380 for (intptr_t i = 0; (i < statements.length()) && instructions.is_open(); | 5385 for (intptr_t i = 0; (i < statements.length()) && instructions.is_open(); |
| 5381 ++i) { | 5386 ++i) { |
| 5382 instructions += TranslateStatement(statements[i]); | 5387 instructions += TranslateStatement(statements[i]); |
| 5383 } | 5388 } |
| 5384 instructions += ExitScope(node); | 5389 instructions += ExitScope(node->kernel_file_offset()); |
| 5385 | 5390 |
| 5386 fragment_ = instructions; | 5391 fragment_ = instructions; |
| 5387 } | 5392 } |
| 5388 | 5393 |
| 5389 | 5394 |
| 5390 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { | 5395 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 5391 bool inside_try_finally = try_finally_block_ != NULL; | 5396 bool inside_try_finally = try_finally_block_ != NULL; |
| 5392 | 5397 |
| 5393 Fragment instructions = node->expression() == NULL | 5398 Fragment instructions = node->expression() == NULL |
| 5394 ? NullConstant() | 5399 ? NullConstant() |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5551 | 5556 |
| 5552 fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit); | 5557 fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit); |
| 5553 --loop_depth_; | 5558 --loop_depth_; |
| 5554 } | 5559 } |
| 5555 | 5560 |
| 5556 | 5561 |
| 5557 void FlowGraphBuilder::VisitForStatement(ForStatement* node) { | 5562 void FlowGraphBuilder::VisitForStatement(ForStatement* node) { |
| 5558 Fragment declarations; | 5563 Fragment declarations; |
| 5559 | 5564 |
| 5560 bool new_context = false; | 5565 bool new_context = false; |
| 5561 declarations += EnterScope(node, &new_context); | 5566 declarations += EnterScope(node->kernel_file_offset(), &new_context); |
| 5562 | 5567 |
| 5563 List<VariableDeclaration>& variables = node->variables(); | 5568 List<VariableDeclaration>& variables = node->variables(); |
| 5564 for (intptr_t i = 0; i < variables.length(); ++i) { | 5569 for (intptr_t i = 0; i < variables.length(); ++i) { |
| 5565 declarations += TranslateStatement(variables[i]); | 5570 declarations += TranslateStatement(variables[i]); |
| 5566 } | 5571 } |
| 5567 | 5572 |
| 5568 ++loop_depth_; | 5573 ++loop_depth_; |
| 5569 bool negate = false; | 5574 bool negate = false; |
| 5570 Fragment condition = node->condition() == NULL | 5575 Fragment condition = node->condition() == NULL |
| 5571 ? Constant(Bool::True()) | 5576 ? Constant(Bool::True()) |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 5597 Fragment loop(join); | 5602 Fragment loop(join); |
| 5598 loop += CheckStackOverflow(); | 5603 loop += CheckStackOverflow(); |
| 5599 loop += condition; | 5604 loop += condition; |
| 5600 } else { | 5605 } else { |
| 5601 declarations += condition; | 5606 declarations += condition; |
| 5602 } | 5607 } |
| 5603 | 5608 |
| 5604 Fragment loop(declarations.entry, loop_exit); | 5609 Fragment loop(declarations.entry, loop_exit); |
| 5605 --loop_depth_; | 5610 --loop_depth_; |
| 5606 | 5611 |
| 5607 loop += ExitScope(node); | 5612 loop += ExitScope(node->kernel_file_offset()); |
| 5608 | 5613 |
| 5609 fragment_ = loop; | 5614 fragment_ = loop; |
| 5610 } | 5615 } |
| 5611 | 5616 |
| 5612 | 5617 |
| 5613 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { | 5618 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) { |
| 5614 Fragment instructions = TranslateExpression(node->iterable()); | 5619 Fragment instructions = TranslateExpression(node->iterable()); |
| 5615 instructions += PushArgument(); | 5620 instructions += PushArgument(); |
| 5616 | 5621 |
| 5617 const dart::String& iterator_getter = dart::String::ZoneHandle( | 5622 const dart::String& iterator_getter = dart::String::ZoneHandle( |
| 5618 Z, dart::Field::GetterSymbol(Symbols::Iterator())); | 5623 Z, dart::Field::GetterSymbol(Symbols::Iterator())); |
| 5619 instructions += InstanceCall(node->iterable()->position(), iterator_getter, | 5624 instructions += InstanceCall(node->iterable()->position(), iterator_getter, |
| 5620 Token::kGET, 1); | 5625 Token::kGET, 1); |
| 5621 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; | 5626 LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_]; |
| 5622 instructions += StoreLocal(TokenPosition::kNoSource, iterator); | 5627 instructions += StoreLocal(TokenPosition::kNoSource, iterator); |
| 5623 instructions += Drop(); | 5628 instructions += Drop(); |
| 5624 | 5629 |
| 5625 ++for_in_depth_; | 5630 ++for_in_depth_; |
| 5626 ++loop_depth_; | 5631 ++loop_depth_; |
| 5627 Fragment condition = LoadLocal(iterator); | 5632 Fragment condition = LoadLocal(iterator); |
| 5628 condition += PushArgument(); | 5633 condition += PushArgument(); |
| 5629 condition += InstanceCall(node->iterable()->position(), Symbols::MoveNext(), | 5634 condition += InstanceCall(node->iterable()->position(), Symbols::MoveNext(), |
| 5630 Token::kILLEGAL, 1); | 5635 Token::kILLEGAL, 1); |
| 5631 TargetEntryInstr* body_entry; | 5636 TargetEntryInstr* body_entry; |
| 5632 TargetEntryInstr* loop_exit; | 5637 TargetEntryInstr* loop_exit; |
| 5633 condition += BranchIfTrue(&body_entry, &loop_exit); | 5638 condition += BranchIfTrue(&body_entry, &loop_exit); |
| 5634 | 5639 |
| 5635 Fragment body(body_entry); | 5640 Fragment body(body_entry); |
| 5636 body += EnterScope(node); | 5641 body += EnterScope(node->kernel_file_offset()); |
| 5637 body += LoadLocal(iterator); | 5642 body += LoadLocal(iterator); |
| 5638 body += PushArgument(); | 5643 body += PushArgument(); |
| 5639 const dart::String& current_getter = dart::String::ZoneHandle( | 5644 const dart::String& current_getter = dart::String::ZoneHandle( |
| 5640 Z, dart::Field::GetterSymbol(Symbols::Current())); | 5645 Z, dart::Field::GetterSymbol(Symbols::Current())); |
| 5641 body += InstanceCall(node->position(), current_getter, Token::kGET, 1); | 5646 body += InstanceCall(node->position(), current_getter, Token::kGET, 1); |
| 5642 body += | 5647 body += |
| 5643 StoreLocal(TokenPosition::kNoSource, LookupVariable(node->variable())); | 5648 StoreLocal(TokenPosition::kNoSource, LookupVariable(node->variable())); |
| 5644 body += Drop(); | 5649 body += Drop(); |
| 5645 body += TranslateStatement(node->body()); | 5650 body += TranslateStatement(node->body()); |
| 5646 body += ExitScope(node); | 5651 body += ExitScope(node->kernel_file_offset()); |
| 5647 | 5652 |
| 5648 if (body.is_open()) { | 5653 if (body.is_open()) { |
| 5649 JoinEntryInstr* join = BuildJoinEntry(); | 5654 JoinEntryInstr* join = BuildJoinEntry(); |
| 5650 instructions += Goto(join); | 5655 instructions += Goto(join); |
| 5651 body += Goto(join); | 5656 body += Goto(join); |
| 5652 | 5657 |
| 5653 Fragment loop(join); | 5658 Fragment loop(join); |
| 5654 loop += CheckStackOverflow(); | 5659 loop += CheckStackOverflow(); |
| 5655 loop += condition; | 5660 loop += condition; |
| 5656 } else { | 5661 } else { |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6083 } | 6088 } |
| 6084 } | 6089 } |
| 6085 Fragment catch_body = | 6090 Fragment catch_body = |
| 6086 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace); | 6091 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace); |
| 6087 // Fill in the body of the catch. | 6092 // Fill in the body of the catch. |
| 6088 for (intptr_t i = 0; i < node->catches().length(); i++) { | 6093 for (intptr_t i = 0; i < node->catches().length(); i++) { |
| 6089 Catch* catch_clause = node->catches()[i]; | 6094 Catch* catch_clause = node->catches()[i]; |
| 6090 | 6095 |
| 6091 Fragment catch_handler_body; | 6096 Fragment catch_handler_body; |
| 6092 | 6097 |
| 6093 catch_handler_body += EnterScope(catch_clause); | 6098 catch_handler_body += EnterScope(catch_clause->kernel_file_offset()); |
| 6094 | 6099 |
| 6095 if (catch_clause->exception() != NULL) { | 6100 if (catch_clause->exception() != NULL) { |
| 6096 catch_handler_body += LoadLocal(CurrentException()); | 6101 catch_handler_body += LoadLocal(CurrentException()); |
| 6097 catch_handler_body += StoreLocal( | 6102 catch_handler_body += StoreLocal( |
| 6098 TokenPosition::kNoSource, LookupVariable(catch_clause->exception())); | 6103 TokenPosition::kNoSource, LookupVariable(catch_clause->exception())); |
| 6099 catch_handler_body += Drop(); | 6104 catch_handler_body += Drop(); |
| 6100 } | 6105 } |
| 6101 if (catch_clause->stack_trace() != NULL) { | 6106 if (catch_clause->stack_trace() != NULL) { |
| 6102 catch_handler_body += LoadLocal(CurrentStackTrace()); | 6107 catch_handler_body += LoadLocal(CurrentStackTrace()); |
| 6103 catch_handler_body += | 6108 catch_handler_body += |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 6115 } | 6120 } |
| 6116 | 6121 |
| 6117 { | 6122 { |
| 6118 CatchBlock block(this, CurrentException(), CurrentStackTrace(), | 6123 CatchBlock block(this, CurrentException(), CurrentStackTrace(), |
| 6119 try_handler_index); | 6124 try_handler_index); |
| 6120 | 6125 |
| 6121 catch_handler_body += TranslateStatement(catch_clause->body()); | 6126 catch_handler_body += TranslateStatement(catch_clause->body()); |
| 6122 | 6127 |
| 6123 // Note: ExitScope adjusts context_depth_ so even if catch_handler_body | 6128 // Note: ExitScope adjusts context_depth_ so even if catch_handler_body |
| 6124 // is closed we still need to execute ExitScope for its side effect. | 6129 // is closed we still need to execute ExitScope for its side effect. |
| 6125 catch_handler_body += ExitScope(catch_clause); | 6130 catch_handler_body += ExitScope(catch_clause->kernel_file_offset()); |
| 6126 if (catch_handler_body.is_open()) { | 6131 if (catch_handler_body.is_open()) { |
| 6127 catch_handler_body += Goto(after_try); | 6132 catch_handler_body += Goto(after_try); |
| 6128 } | 6133 } |
| 6129 } | 6134 } |
| 6130 | 6135 |
| 6131 if (type_guard != NULL) { | 6136 if (type_guard != NULL) { |
| 6132 if (type_guard->IsMalformed()) { | 6137 if (type_guard->IsMalformed()) { |
| 6133 catch_body += ThrowTypeError(); | 6138 catch_body += ThrowTypeError(); |
| 6134 catch_body += Drop(); | 6139 catch_body += Drop(); |
| 6135 } else { | 6140 } else { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6249 fragment_ = continuation; | 6254 fragment_ = continuation; |
| 6250 } | 6255 } |
| 6251 | 6256 |
| 6252 | 6257 |
| 6253 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, | 6258 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, |
| 6254 TreeNode* parent) { | 6259 TreeNode* parent) { |
| 6255 // The VM has a per-isolate table of functions indexed by the enclosing | 6260 // The VM has a per-isolate table of functions indexed by the enclosing |
| 6256 // function and token position. | 6261 // function and token position. |
| 6257 Function& function = Function::ZoneHandle(Z); | 6262 Function& function = Function::ZoneHandle(Z); |
| 6258 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) { | 6263 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) { |
| 6259 if (scopes_->function_scopes[i].function != node) continue; | 6264 if (scopes_->function_scopes[i].kernelFileOffset != |
| 6265 node->kernel_file_offset()) { | |
| 6266 continue; | |
| 6267 } | |
| 6260 | 6268 |
| 6261 TokenPosition position = node->position(); | 6269 TokenPosition position = node->position(); |
| 6262 if (parent->IsFunctionDeclaration()) { | 6270 if (parent->IsFunctionDeclaration()) { |
| 6263 position = FunctionDeclaration::Cast(parent)->position(); | 6271 position = FunctionDeclaration::Cast(parent)->position(); |
| 6264 } | 6272 } |
| 6265 if (!position.IsReal()) { | 6273 if (!position.IsReal()) { |
| 6266 // Positions has to be unique in regards to the parent. | 6274 // Positions has to be unique in regards to the parent. |
| 6267 // A non-real at this point is probably -1, we cannot blindly use that | 6275 // A non-real at this point is probably -1, we cannot blindly use that |
| 6268 // as others might use it too. Create a new dummy non-real TokenPosition. | 6276 // as others might use it too. Create a new dummy non-real TokenPosition. |
| 6269 position = TokenPosition(i).ToSynthetic(); | 6277 position = TokenPosition(i).ToSynthetic(); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6458 thread->clear_sticky_error(); | 6466 thread->clear_sticky_error(); |
| 6459 return error.raw(); | 6467 return error.raw(); |
| 6460 } | 6468 } |
| 6461 } | 6469 } |
| 6462 | 6470 |
| 6463 | 6471 |
| 6464 } // namespace kernel | 6472 } // namespace kernel |
| 6465 } // namespace dart | 6473 } // namespace dart |
| 6466 | 6474 |
| 6467 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6475 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |