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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 void ScopeBuilder::EnterScope(TreeNode* node, TokenPosition start_position) { |
62 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); | 62 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); |
63 scope_->set_begin_token_pos(start_position); | 63 scope_->set_begin_token_pos(start_position); |
64 ASSERT(node->kernel_offset() >= 0); | 64 result_->scopes.Insert(node, scope_); |
65 result_->scopes.Insert(node->kernel_offset(), scope_); | |
66 } | 65 } |
67 | 66 |
68 | 67 |
69 void ScopeBuilder::ExitScope(TokenPosition end_position) { | 68 void ScopeBuilder::ExitScope(TokenPosition end_position) { |
70 scope_->set_end_token_pos(end_position); | 69 scope_->set_end_token_pos(end_position); |
71 scope_ = scope_->parent(); | 70 scope_ = scope_->parent(); |
72 } | 71 } |
73 | 72 |
74 | 73 |
75 LocalVariable* ScopeBuilder::MakeVariable(TokenPosition declaration_pos, | 74 LocalVariable* ScopeBuilder::MakeVariable(TokenPosition declaration_pos, |
(...skipping 18 matching lines...) Expand all Loading... |
94 | 93 |
95 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, | 94 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, |
96 intptr_t pos) { | 95 intptr_t pos) { |
97 LocalVariable* variable = MakeVariable( | 96 LocalVariable* variable = MakeVariable( |
98 declaration->position(), declaration->position(), | 97 declaration->position(), declaration->position(), |
99 H.DartSymbol(declaration->name()), T.TranslateVariableType(declaration)); | 98 H.DartSymbol(declaration->name()), T.TranslateVariableType(declaration)); |
100 if (declaration->IsFinal()) { | 99 if (declaration->IsFinal()) { |
101 variable->set_is_final(); | 100 variable->set_is_final(); |
102 } | 101 } |
103 scope_->InsertParameterAt(pos, variable); | 102 scope_->InsertParameterAt(pos, variable); |
104 result_->locals.Insert(declaration->kernel_offset(), variable); | 103 result_->locals.Insert(declaration, variable); |
105 | 104 |
106 // The default value may contain 'let' bindings for which the constant | 105 // The default value may contain 'let' bindings for which the constant |
107 // evaluator needs scope bindings. | 106 // evaluator needs scope bindings. |
108 Expression* defaultValue = declaration->initializer(); | 107 Expression* defaultValue = declaration->initializer(); |
109 if (defaultValue != NULL) { | 108 if (defaultValue != NULL) { |
110 defaultValue->AcceptExpressionVisitor(this); | 109 defaultValue->AcceptExpressionVisitor(this); |
111 } | 110 } |
112 } | 111 } |
113 | 112 |
114 | 113 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 LocalVariable* iterator = | 178 LocalVariable* iterator = |
180 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 179 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
181 GenerateName(":iterator", depth_.for_in_ - 1), | 180 GenerateName(":iterator", depth_.for_in_ - 1), |
182 AbstractType::dynamic_type()); | 181 AbstractType::dynamic_type()); |
183 current_function_scope_->AddVariable(iterator); | 182 current_function_scope_->AddVariable(iterator); |
184 result_->iterator_variables.Add(iterator); | 183 result_->iterator_variables.Add(iterator); |
185 } | 184 } |
186 | 185 |
187 | 186 |
188 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { | 187 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { |
189 LocalVariable* variable = | 188 LocalVariable* variable = result_->locals.Lookup(declaration); |
190 result_->locals.Lookup(declaration->kernel_offset()); | |
191 if (variable == NULL) { | 189 if (variable == NULL) { |
192 // We have not seen a declaration of the variable, so it must be the | 190 // We have not seen a declaration of the variable, so it must be the |
193 // case that we are compiling a nested function and the variable is | 191 // case that we are compiling a nested function and the variable is |
194 // declared in an outer scope. In that case, look it up in the scope by | 192 // declared in an outer scope. In that case, look it up in the scope by |
195 // name and add it to the variable map to simplify later lookup. | 193 // name and add it to the variable map to simplify later lookup. |
196 ASSERT(current_function_scope_->parent() != NULL); | 194 ASSERT(current_function_scope_->parent() != NULL); |
197 const dart::String& name = H.DartSymbol(declaration->name()); | 195 const dart::String& name = H.DartSymbol(declaration->name()); |
198 variable = current_function_scope_->parent()->LookupVariable(name, true); | 196 variable = current_function_scope_->parent()->LookupVariable(name, true); |
199 ASSERT(variable != NULL); | 197 ASSERT(variable != NULL); |
200 result_->locals.Insert(declaration->kernel_offset(), variable); | 198 result_->locals.Insert(declaration, variable); |
201 } | 199 } |
202 if (variable->owner()->function_level() < scope_->function_level()) { | 200 if (variable->owner()->function_level() < scope_->function_level()) { |
203 // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two | 201 // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two |
204 // different reasons: | 202 // different reasons: |
205 // Scenario 1: | 203 // Scenario 1: |
206 // We need to know which variables defined in this function | 204 // We need to know which variables defined in this function |
207 // are closed over by nested closures in order to ensure we will | 205 // are closed over by nested closures in order to ensure we will |
208 // create a [Context] object of appropriate size and store captured | 206 // create a [Context] object of appropriate size and store captured |
209 // variables there instead of the stack. | 207 // variables there instead of the stack. |
210 // Scenario 2: | 208 // Scenario 2: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 const dart::String& name = declaration->name()->is_empty() | 242 const dart::String& name = declaration->name()->is_empty() |
245 ? GenerateName(":var", name_index_++) | 243 ? GenerateName(":var", name_index_++) |
246 : H.DartSymbol(declaration->name()); | 244 : H.DartSymbol(declaration->name()); |
247 LocalVariable* variable = | 245 LocalVariable* variable = |
248 MakeVariable(declaration->position(), declaration->end_position(), name, | 246 MakeVariable(declaration->position(), declaration->end_position(), name, |
249 T.TranslateVariableType(declaration)); | 247 T.TranslateVariableType(declaration)); |
250 if (declaration->IsFinal()) { | 248 if (declaration->IsFinal()) { |
251 variable->set_is_final(); | 249 variable->set_is_final(); |
252 } | 250 } |
253 scope_->AddVariable(variable); | 251 scope_->AddVariable(variable); |
254 result_->locals.Insert(declaration->kernel_offset(), variable); | 252 result_->locals.Insert(declaration, variable); |
255 } | 253 } |
256 | 254 |
257 | 255 |
258 static bool IsStaticInitializer(const Function& function, Zone* zone) { | 256 static bool IsStaticInitializer(const Function& function, Zone* zone) { |
259 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && | 257 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && |
260 dart::String::Handle(zone, function.name()) | 258 dart::String::Handle(zone, function.name()) |
261 .StartsWith(Symbols::InitPrefix()); | 259 .StartsWith(Symbols::InitPrefix()); |
262 } | 260 } |
263 | 261 |
264 | 262 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 void ScopeBuilder::HandleLocalFunction(TreeNode* parent, | 485 void ScopeBuilder::HandleLocalFunction(TreeNode* parent, |
488 FunctionNode* function) { | 486 FunctionNode* function) { |
489 LocalScope* saved_function_scope = current_function_scope_; | 487 LocalScope* saved_function_scope = current_function_scope_; |
490 FunctionNode* saved_function_node = current_function_node_; | 488 FunctionNode* saved_function_node = current_function_node_; |
491 ScopeBuilder::DepthState saved_depth_state = depth_; | 489 ScopeBuilder::DepthState saved_depth_state = depth_; |
492 depth_ = DepthState(depth_.function_ + 1); | 490 depth_ = DepthState(depth_.function_ + 1); |
493 EnterScope(parent, function->position()); | 491 EnterScope(parent, function->position()); |
494 current_function_scope_ = scope_; | 492 current_function_scope_ = scope_; |
495 current_function_node_ = function; | 493 current_function_node_ = function; |
496 if (depth_.function_ == 1) { | 494 if (depth_.function_ == 1) { |
497 FunctionScope function_scope = {function->kernel_offset(), scope_}; | 495 FunctionScope function_scope = {function, scope_}; |
498 result_->function_scopes.Add(function_scope); | 496 result_->function_scopes.Add(function_scope); |
499 } | 497 } |
500 AddParameters(function); | 498 AddParameters(function); |
501 VisitFunctionNode(function); | 499 VisitFunctionNode(function); |
502 ExitScope(function->end_position()); | 500 ExitScope(function->end_position()); |
503 depth_ = saved_depth_state; | 501 depth_ = saved_depth_state; |
504 current_function_scope_ = saved_function_scope; | 502 current_function_scope_ = saved_function_scope; |
505 current_function_node_ = saved_function_node; | 503 current_function_node_ = saved_function_node; |
506 } | 504 } |
507 | 505 |
(...skipping 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 context_depth_ = saved_depth; | 2007 context_depth_ = saved_depth; |
2010 try_depth_ = saved_try_depth; | 2008 try_depth_ = saved_try_depth; |
2011 | 2009 |
2012 return instructions; | 2010 return instructions; |
2013 } | 2011 } |
2014 | 2012 |
2015 | 2013 |
2016 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { | 2014 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) { |
2017 Fragment instructions; | 2015 Fragment instructions; |
2018 const intptr_t context_size = | 2016 const intptr_t context_size = |
2019 scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables(); | 2017 scopes_->scopes.Lookup(node)->num_context_variables(); |
2020 if (context_size > 0) { | 2018 if (context_size > 0) { |
2021 instructions += PushContext(context_size); | 2019 instructions += PushContext(context_size); |
2022 instructions += Drop(); | 2020 instructions += Drop(); |
2023 if (new_context != NULL) { | 2021 if (new_context != NULL) { |
2024 *new_context = true; | 2022 *new_context = true; |
2025 } | 2023 } |
2026 } | 2024 } |
2027 return instructions; | 2025 return instructions; |
2028 } | 2026 } |
2029 | 2027 |
2030 | 2028 |
2031 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) { | 2029 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) { |
2032 Fragment instructions; | 2030 Fragment instructions; |
2033 const intptr_t context_size = | 2031 const intptr_t context_size = |
2034 scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables(); | 2032 scopes_->scopes.Lookup(node)->num_context_variables(); |
2035 if (context_size > 0) { | 2033 if (context_size > 0) { |
2036 instructions += PopContext(); | 2034 instructions += PopContext(); |
2037 } | 2035 } |
2038 return instructions; | 2036 return instructions; |
2039 } | 2037 } |
2040 | 2038 |
2041 | 2039 |
2042 Fragment FlowGraphBuilder::LoadContextAt(int depth) { | 2040 Fragment FlowGraphBuilder::LoadContextAt(int depth) { |
2043 intptr_t delta = context_depth_ - depth; | 2041 intptr_t delta = context_depth_ - depth; |
2044 ASSERT(delta >= 0); | 2042 ASSERT(delta >= 0); |
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2877 if (try_catch_block_ == NULL) { | 2875 if (try_catch_block_ == NULL) { |
2878 return CatchClauseNode::kInvalidTryIndex; | 2876 return CatchClauseNode::kInvalidTryIndex; |
2879 } else { | 2877 } else { |
2880 return try_catch_block_->try_index(); | 2878 return try_catch_block_->try_index(); |
2881 } | 2879 } |
2882 } | 2880 } |
2883 | 2881 |
2884 | 2882 |
2885 dart::LocalVariable* FlowGraphBuilder::LookupVariable( | 2883 dart::LocalVariable* FlowGraphBuilder::LookupVariable( |
2886 VariableDeclaration* var) { | 2884 VariableDeclaration* var) { |
2887 LocalVariable* local = scopes_->locals.Lookup(var->kernel_offset()); | 2885 LocalVariable* local = scopes_->locals.Lookup(var); |
2888 ASSERT(local != NULL); | 2886 ASSERT(local != NULL); |
2889 return local; | 2887 return local; |
2890 } | 2888 } |
2891 | 2889 |
2892 | 2890 |
2893 void FlowGraphBuilder::SetTempIndex(Definition* definition) { | 2891 void FlowGraphBuilder::SetTempIndex(Definition* definition) { |
2894 definition->set_temp_index( | 2892 definition->set_temp_index( |
2895 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); | 2893 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); |
2896 } | 2894 } |
2897 | 2895 |
(...skipping 3354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6252 fragment_ = continuation; | 6250 fragment_ = continuation; |
6253 } | 6251 } |
6254 | 6252 |
6255 | 6253 |
6256 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, | 6254 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, |
6257 TreeNode* parent) { | 6255 TreeNode* parent) { |
6258 // The VM has a per-isolate table of functions indexed by the enclosing | 6256 // The VM has a per-isolate table of functions indexed by the enclosing |
6259 // function and token position. | 6257 // function and token position. |
6260 Function& function = Function::ZoneHandle(Z); | 6258 Function& function = Function::ZoneHandle(Z); |
6261 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) { | 6259 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) { |
6262 if (scopes_->function_scopes[i].kernel_offset != node->kernel_offset()) { | 6260 if (scopes_->function_scopes[i].function != node) continue; |
6263 continue; | |
6264 } | |
6265 | 6261 |
6266 TokenPosition position = node->position(); | 6262 TokenPosition position = node->position(); |
6267 if (parent->IsFunctionDeclaration()) { | 6263 if (parent->IsFunctionDeclaration()) { |
6268 position = FunctionDeclaration::Cast(parent)->position(); | 6264 position = FunctionDeclaration::Cast(parent)->position(); |
6269 } | 6265 } |
6270 if (!position.IsReal()) { | 6266 if (!position.IsReal()) { |
6271 // Positions has to be unique in regards to the parent. | 6267 // Positions has to be unique in regards to the parent. |
6272 // A non-real at this point is probably -1, we cannot blindly use that | 6268 // A non-real at this point is probably -1, we cannot blindly use that |
6273 // as others might use it too. Create a new dummy non-real TokenPosition. | 6269 // as others might use it too. Create a new dummy non-real TokenPosition. |
6274 position = TokenPosition(i).ToSynthetic(); | 6270 position = TokenPosition(i).ToSynthetic(); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6463 thread->clear_sticky_error(); | 6459 thread->clear_sticky_error(); |
6464 return error.raw(); | 6460 return error.raw(); |
6465 } | 6461 } |
6466 } | 6462 } |
6467 | 6463 |
6468 | 6464 |
6469 } // namespace kernel | 6465 } // namespace kernel |
6470 } // namespace dart | 6466 } // namespace dart |
6471 | 6467 |
6472 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6468 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |