| 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 |