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