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 |