| 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 12 matching lines...) Expand all Loading... |
| 23 DECLARE_FLAG(bool, support_externalizable_strings); | 23 DECLARE_FLAG(bool, support_externalizable_strings); |
| 24 | 24 |
| 25 namespace kernel { | 25 namespace kernel { |
| 26 | 26 |
| 27 #define Z (zone_) | 27 #define Z (zone_) |
| 28 #define H (translation_helper_) | 28 #define H (translation_helper_) |
| 29 #define T (type_translator_) | 29 #define T (type_translator_) |
| 30 #define I Isolate::Current() | 30 #define I Isolate::Current() |
| 31 | 31 |
| 32 | 32 |
| 33 static void DiscoverEnclosingElements(Zone* zone, |
| 34 const Function& function, |
| 35 Function* outermost_function, |
| 36 TreeNode** outermost_node, |
| 37 Class** klass) { |
| 38 // Find out if there is an enclosing kernel class (which will be used to |
| 39 // resolve type parameters). |
| 40 *outermost_function = function.raw(); |
| 41 while (outermost_function->parent_function() != Object::null()) { |
| 42 *outermost_function = outermost_function->parent_function(); |
| 43 } |
| 44 *outermost_node = |
| 45 static_cast<TreeNode*>(outermost_function->kernel_function()); |
| 46 if (*outermost_node != NULL) { |
| 47 TreeNode* parent = NULL; |
| 48 if ((*outermost_node)->IsProcedure()) { |
| 49 parent = Procedure::Cast(*outermost_node)->parent(); |
| 50 } else if ((*outermost_node)->IsConstructor()) { |
| 51 parent = Constructor::Cast(*outermost_node)->parent(); |
| 52 } else if ((*outermost_node)->IsField()) { |
| 53 parent = Field::Cast(*outermost_node)->parent(); |
| 54 } |
| 55 if (parent != NULL && parent->IsClass()) *klass = Class::Cast(parent); |
| 56 } |
| 57 } |
| 58 |
| 59 |
| 33 void ScopeBuilder::EnterScope(TreeNode* node) { | 60 void ScopeBuilder::EnterScope(TreeNode* node) { |
| 34 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); | 61 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); |
| 35 result_->scopes.Insert(node, scope_); | 62 result_->scopes.Insert(node, scope_); |
| 36 } | 63 } |
| 37 | 64 |
| 38 | 65 |
| 39 void ScopeBuilder::ExitScope() { scope_ = scope_->parent(); } | 66 void ScopeBuilder::ExitScope() { scope_ = scope_->parent(); } |
| 40 | 67 |
| 41 | 68 |
| 42 LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name) { | |
| 43 return new (Z) | |
| 44 LocalVariable(TokenPosition::kNoSource, | |
| 45 TokenPosition::kNoSource, | |
| 46 name, | |
| 47 Object::dynamic_type()); | |
| 48 } | |
| 49 | |
| 50 | |
| 51 LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name, | 69 LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name, |
| 52 const Type& type) { | 70 const AbstractType& type) { |
| 53 return new (Z) LocalVariable(TokenPosition::kNoSource, | 71 return new (Z) LocalVariable(TokenPosition::kNoSource, |
| 54 TokenPosition::kNoSource, | 72 TokenPosition::kNoSource, |
| 55 name, | 73 name, |
| 56 type); | 74 type); |
| 57 } | 75 } |
| 58 | 76 |
| 59 | 77 |
| 60 void ScopeBuilder::AddParameters(FunctionNode* function, intptr_t pos) { | 78 void ScopeBuilder::AddParameters(FunctionNode* function, intptr_t pos) { |
| 61 List<VariableDeclaration>& positional = function->positional_parameters(); | 79 List<VariableDeclaration>& positional = function->positional_parameters(); |
| 62 for (intptr_t i = 0; i < positional.length(); ++i) { | 80 for (intptr_t i = 0; i < positional.length(); ++i) { |
| 63 AddParameter(positional[i], pos++); | 81 AddParameter(positional[i], pos++); |
| 64 } | 82 } |
| 65 List<VariableDeclaration>& named = function->named_parameters(); | 83 List<VariableDeclaration>& named = function->named_parameters(); |
| 66 for (intptr_t i = 0; i < named.length(); ++i) { | 84 for (intptr_t i = 0; i < named.length(); ++i) { |
| 67 AddParameter(named[i], pos++); | 85 AddParameter(named[i], pos++); |
| 68 } | 86 } |
| 69 } | 87 } |
| 70 | 88 |
| 71 | 89 |
| 72 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, | 90 void ScopeBuilder::AddParameter(VariableDeclaration* declaration, |
| 73 intptr_t pos) { | 91 intptr_t pos) { |
| 74 LocalVariable* variable = MakeVariable(H.DartSymbol(declaration->name())); | 92 LocalVariable* variable = |
| 93 MakeVariable(H.DartSymbol(declaration->name()), |
| 94 T.TranslateVariableType(declaration)); |
| 75 if (declaration->IsFinal()) { | 95 if (declaration->IsFinal()) { |
| 76 variable->set_is_final(); | 96 variable->set_is_final(); |
| 77 } | 97 } |
| 78 scope_->InsertParameterAt(pos, variable); | 98 scope_->InsertParameterAt(pos, variable); |
| 79 result_->locals.Insert(declaration, variable); | 99 result_->locals.Insert(declaration, variable); |
| 80 | 100 |
| 81 // The default value may contain 'let' bindings for which the constant | 101 // The default value may contain 'let' bindings for which the constant |
| 82 // evaluator needs scope bindings. | 102 // evaluator needs scope bindings. |
| 83 Expression* defaultValue = declaration->initializer(); | 103 Expression* defaultValue = declaration->initializer(); |
| 84 if (defaultValue != NULL) { | 104 if (defaultValue != NULL) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 110 } | 130 } |
| 111 | 131 |
| 112 // No need to create variables for try/catch-statements inside | 132 // No need to create variables for try/catch-statements inside |
| 113 // nested functions. | 133 // nested functions. |
| 114 if (depth_.function_ > 0) return; | 134 if (depth_.function_ > 0) return; |
| 115 if (variables->length() >= nesting_depth) return; | 135 if (variables->length() >= nesting_depth) return; |
| 116 | 136 |
| 117 // If variable was not lifted by the transformer introduce a new | 137 // If variable was not lifted by the transformer introduce a new |
| 118 // one into the current function scope. | 138 // one into the current function scope. |
| 119 if (v == NULL) { | 139 if (v == NULL) { |
| 120 v = MakeVariable(GenerateName(prefix, nesting_depth - 1)); | 140 v = MakeVariable(GenerateName(prefix, nesting_depth - 1), |
| 141 AbstractType::dynamic_type()); |
| 121 | 142 |
| 122 // If transformer did not lift the variable then there is no need | 143 // If transformer did not lift the variable then there is no need |
| 123 // to lift it into the context when we encouter a YieldStatement. | 144 // to lift it into the context when we encouter a YieldStatement. |
| 124 v->set_is_forced_stack(); | 145 v->set_is_forced_stack(); |
| 125 current_function_scope_->AddVariable(v); | 146 current_function_scope_->AddVariable(v); |
| 126 } | 147 } |
| 127 | 148 |
| 128 variables->Add(v); | 149 variables->Add(v); |
| 129 } | 150 } |
| 130 | 151 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 142 depth_.catch_); | 163 depth_.catch_); |
| 143 } | 164 } |
| 144 | 165 |
| 145 | 166 |
| 146 void ScopeBuilder::AddIteratorVariable() { | 167 void ScopeBuilder::AddIteratorVariable() { |
| 147 if (depth_.function_ > 0) return; | 168 if (depth_.function_ > 0) return; |
| 148 if (result_->iterator_variables.length() >= depth_.for_in_) return; | 169 if (result_->iterator_variables.length() >= depth_.for_in_) return; |
| 149 | 170 |
| 150 ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1); | 171 ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1); |
| 151 LocalVariable* iterator = | 172 LocalVariable* iterator = |
| 152 MakeVariable(GenerateName(":iterator", depth_.for_in_ - 1)); | 173 MakeVariable(GenerateName(":iterator", depth_.for_in_ - 1), |
| 174 AbstractType::dynamic_type()); |
| 153 current_function_scope_->AddVariable(iterator); | 175 current_function_scope_->AddVariable(iterator); |
| 154 result_->iterator_variables.Add(iterator); | 176 result_->iterator_variables.Add(iterator); |
| 155 } | 177 } |
| 156 | 178 |
| 157 | 179 |
| 158 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { | 180 void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) { |
| 159 LocalVariable* variable = result_->locals.Lookup(declaration); | 181 LocalVariable* variable = result_->locals.Lookup(declaration); |
| 160 if (variable == NULL) { | 182 if (variable == NULL) { |
| 161 // We have not seen a declaration of the variable, so it must be the | 183 // We have not seen a declaration of the variable, so it must be the |
| 162 // case that we are compiling a nested function and the variable is | 184 // case that we are compiling a nested function and the variable is |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 228 } |
| 207 | 229 |
| 208 | 230 |
| 209 void ScopeBuilder::AddVariable(VariableDeclaration* declaration) { | 231 void ScopeBuilder::AddVariable(VariableDeclaration* declaration) { |
| 210 // In case `declaration->IsConst()` the flow graph building will take care of | 232 // In case `declaration->IsConst()` the flow graph building will take care of |
| 211 // evaluating the constant and setting it via | 233 // evaluating the constant and setting it via |
| 212 // `declaration->SetConstantValue()`. | 234 // `declaration->SetConstantValue()`. |
| 213 const dart::String& name = declaration->name()->is_empty() | 235 const dart::String& name = declaration->name()->is_empty() |
| 214 ? GenerateName(":var", name_index_++) | 236 ? GenerateName(":var", name_index_++) |
| 215 : H.DartSymbol(declaration->name()); | 237 : H.DartSymbol(declaration->name()); |
| 216 LocalVariable* variable = MakeVariable(name); | 238 LocalVariable* variable = |
| 239 MakeVariable(name, T.TranslateVariableType(declaration)); |
| 217 if (declaration->IsFinal()) { | 240 if (declaration->IsFinal()) { |
| 218 variable->set_is_final(); | 241 variable->set_is_final(); |
| 219 } | 242 } |
| 220 scope_->AddVariable(variable); | 243 scope_->AddVariable(variable); |
| 221 result_->locals.Insert(declaration, variable); | 244 result_->locals.Insert(declaration, variable); |
| 222 } | 245 } |
| 223 | 246 |
| 224 | 247 |
| 225 static bool IsStaticInitializer(const Function& function, Zone* zone) { | 248 static bool IsStaticInitializer(const Function& function, Zone* zone) { |
| 226 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && | 249 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && |
| 227 dart::String::Handle(zone, function.name()) | 250 dart::String::Handle(zone, function.name()) |
| 228 .StartsWith(Symbols::InitPrefix()); | 251 .StartsWith(Symbols::InitPrefix()); |
| 229 } | 252 } |
| 230 | 253 |
| 231 | 254 |
| 232 ScopeBuildingResult* ScopeBuilder::BuildScopes() { | 255 ScopeBuildingResult* ScopeBuilder::BuildScopes() { |
| 233 if (result_ != NULL) return result_; | 256 if (result_ != NULL) return result_; |
| 234 | 257 |
| 235 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); | 258 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); |
| 236 result_ = new (Z) ScopeBuildingResult(); | 259 result_ = new (Z) ScopeBuildingResult(); |
| 237 | 260 |
| 238 ParsedFunction* parsed_function = parsed_function_; | 261 ParsedFunction* parsed_function = parsed_function_; |
| 239 const dart::Function& function = parsed_function->function(); | 262 const dart::Function& function = parsed_function->function(); |
| 240 | 263 |
| 264 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used |
| 265 // e.g. for type translation. |
| 266 const dart::Class& klass = |
| 267 dart::Class::Handle(zone_, parsed_function_->function().Owner()); |
| 268 Function& outermost_function = Function::Handle(Z); |
| 269 TreeNode* outermost_node = NULL; |
| 270 Class* kernel_klass = NULL; |
| 271 DiscoverEnclosingElements( |
| 272 Z, function, &outermost_function, &outermost_node, &kernel_klass); |
| 273 // Use [klass]/[kernel_klass] as active class. Type parameters will get |
| 274 // resolved via [kernel_klass] unless we are nested inside a static factory |
| 275 // in which case we will use [member]. |
| 276 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass); |
| 277 Member* member = ((outermost_node != NULL) && outermost_node->IsMember()) |
| 278 ? Member::Cast(outermost_node) |
| 279 : NULL; |
| 280 ActiveMemberScope active_member(&active_class_, member); |
| 281 |
| 282 |
| 241 LocalScope* enclosing_scope = NULL; | 283 LocalScope* enclosing_scope = NULL; |
| 242 if (function.IsLocalFunction()) { | 284 if (function.IsLocalFunction()) { |
| 243 enclosing_scope = LocalScope::RestoreOuterScope( | 285 enclosing_scope = LocalScope::RestoreOuterScope( |
| 244 ContextScope::Handle(Z, function.context_scope())); | 286 ContextScope::Handle(Z, function.context_scope())); |
| 245 } | 287 } |
| 246 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); | 288 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); |
| 247 | 289 |
| 248 LocalVariable* context_var = parsed_function->current_context_var(); | 290 LocalVariable* context_var = parsed_function->current_context_var(); |
| 249 context_var->set_is_forced_stack(); | 291 context_var->set_is_forced_stack(); |
| 250 scope_->AddVariable(context_var); | 292 scope_->AddVariable(context_var); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 264 node = Procedure::Cast(node_)->function(); | 306 node = Procedure::Cast(node_)->function(); |
| 265 } else if (node_->IsConstructor()) { | 307 } else if (node_->IsConstructor()) { |
| 266 node = Constructor::Cast(node_)->function(); | 308 node = Constructor::Cast(node_)->function(); |
| 267 } else { | 309 } else { |
| 268 node = FunctionNode::Cast(node_); | 310 node = FunctionNode::Cast(node_); |
| 269 } | 311 } |
| 270 current_function_node_ = node; | 312 current_function_node_ = node; |
| 271 | 313 |
| 272 intptr_t pos = 0; | 314 intptr_t pos = 0; |
| 273 if (function.IsClosureFunction()) { | 315 if (function.IsClosureFunction()) { |
| 274 LocalVariable* variable = MakeVariable(Symbols::ClosureParameter()); | 316 LocalVariable* variable = |
| 317 MakeVariable(Symbols::ClosureParameter(), |
| 318 AbstractType::dynamic_type()); |
| 275 variable->set_is_forced_stack(); | 319 variable->set_is_forced_stack(); |
| 276 scope_->InsertParameterAt(pos++, variable); | 320 scope_->InsertParameterAt(pos++, variable); |
| 277 } else if (!function.is_static()) { | 321 } else if (!function.is_static()) { |
| 278 // We use [is_static] instead of [IsStaticFunction] because the latter | 322 // We use [is_static] instead of [IsStaticFunction] because the latter |
| 279 // returns `false` for constructors. | 323 // returns `false` for constructors. |
| 280 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); | 324 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 281 Type& klass_type = H.GetCanonicalType(klass); | 325 Type& klass_type = H.GetCanonicalType(klass); |
| 282 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); | 326 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); |
| 283 scope_->InsertParameterAt(pos++, variable); | 327 scope_->InsertParameterAt(pos++, variable); |
| 284 result_->this_variable = variable; | 328 result_->this_variable = variable; |
| 285 | 329 |
| 286 // We visit instance field initializers because they might contain | 330 // We visit instance field initializers because they might contain |
| 287 // [Let] expressions and we need to have a mapping. | 331 // [Let] expressions and we need to have a mapping. |
| 288 if (node_->IsConstructor()) { | 332 if (node_->IsConstructor()) { |
| 289 Class* klass = Class::Cast(Constructor::Cast(node_)->parent()); | 333 Class* klass = Class::Cast(Constructor::Cast(node_)->parent()); |
| 290 | 334 |
| 291 for (intptr_t i = 0; i < klass->fields().length(); i++) { | 335 for (intptr_t i = 0; i < klass->fields().length(); i++) { |
| 292 Field* field = klass->fields()[i]; | 336 Field* field = klass->fields()[i]; |
| 293 if (!field->IsStatic() && (field->initializer() != NULL)) { | 337 if (!field->IsStatic() && (field->initializer() != NULL)) { |
| 294 EnterScope(field); | 338 EnterScope(field); |
| 295 field->initializer()->AcceptExpressionVisitor(this); | 339 field->initializer()->AcceptExpressionVisitor(this); |
| 296 ExitScope(); | 340 ExitScope(); |
| 297 } | 341 } |
| 298 } | 342 } |
| 299 } | 343 } |
| 300 } else if (function.IsFactory()) { | 344 } else if (function.IsFactory()) { |
| 301 LocalVariable* variable = MakeVariable( | 345 LocalVariable* variable = MakeVariable( |
| 302 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type()); | 346 Symbols::TypeArgumentsParameter(), |
| 347 AbstractType::dynamic_type()); |
| 303 scope_->InsertParameterAt(pos++, variable); | 348 scope_->InsertParameterAt(pos++, variable); |
| 304 result_->type_arguments_variable = variable; | 349 result_->type_arguments_variable = variable; |
| 305 } | 350 } |
| 306 AddParameters(node, pos); | 351 AddParameters(node, pos); |
| 307 | 352 |
| 308 // We generate a syntethic body for implicit closure functions - which | 353 // We generate a syntethic body for implicit closure functions - which |
| 309 // will forward the call to the real function. | 354 // will forward the call to the real function. |
| 310 // -> see BuildGraphOfImplicitClosureFunction | 355 // -> see BuildGraphOfImplicitClosureFunction |
| 311 if (!function.IsImplicitClosureFunction()) { | 356 if (!function.IsImplicitClosureFunction()) { |
| 312 node_->AcceptVisitor(this); | 357 node_->AcceptVisitor(this); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 325 bool is_method = !function.IsStaticFunction(); | 370 bool is_method = !function.IsStaticFunction(); |
| 326 intptr_t pos = 0; | 371 intptr_t pos = 0; |
| 327 if (is_method) { | 372 if (is_method) { |
| 328 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); | 373 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 329 Type& klass_type = H.GetCanonicalType(klass); | 374 Type& klass_type = H.GetCanonicalType(klass); |
| 330 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); | 375 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); |
| 331 scope_->InsertParameterAt(pos++, variable); | 376 scope_->InsertParameterAt(pos++, variable); |
| 332 result_->this_variable = variable; | 377 result_->this_variable = variable; |
| 333 } | 378 } |
| 334 if (is_setter) { | 379 if (is_setter) { |
| 335 result_->setter_value = MakeVariable(Symbols::Value()); | 380 result_->setter_value = MakeVariable( |
| 381 Symbols::Value(), AbstractType::dynamic_type()); |
| 336 scope_->InsertParameterAt(pos++, result_->setter_value); | 382 scope_->InsertParameterAt(pos++, result_->setter_value); |
| 337 } | 383 } |
| 338 break; | 384 break; |
| 339 } | 385 } |
| 340 case RawFunction::kMethodExtractor: { | 386 case RawFunction::kMethodExtractor: { |
| 341 // Add a receiver parameter. Though it is captured, we emit code to | 387 // Add a receiver parameter. Though it is captured, we emit code to |
| 342 // explicitly copy it to a fixed offset in a freshly-allocated context | 388 // explicitly copy it to a fixed offset in a freshly-allocated context |
| 343 // instead of using the generic code for regular functions. | 389 // instead of using the generic code for regular functions. |
| 344 // Therefore, it isn't necessary to mark it as captured here. | 390 // Therefore, it isn't necessary to mark it as captured here. |
| 345 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); | 391 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 346 Type& klass_type = H.GetCanonicalType(klass); | 392 Type& klass_type = H.GetCanonicalType(klass); |
| 347 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); | 393 LocalVariable* variable = MakeVariable(Symbols::This(), klass_type); |
| 348 scope_->InsertParameterAt(0, variable); | 394 scope_->InsertParameterAt(0, variable); |
| 349 result_->this_variable = variable; | 395 result_->this_variable = variable; |
| 350 break; | 396 break; |
| 351 } | 397 } |
| 352 case RawFunction::kNoSuchMethodDispatcher: | 398 case RawFunction::kNoSuchMethodDispatcher: |
| 353 case RawFunction::kInvokeFieldDispatcher: | 399 case RawFunction::kInvokeFieldDispatcher: |
| 354 for (intptr_t i = 0; i < function.NumParameters(); ++i) { | 400 for (intptr_t i = 0; i < function.NumParameters(); ++i) { |
| 355 LocalVariable* variable = MakeVariable( | 401 LocalVariable* variable = MakeVariable( |
| 356 dart::String::ZoneHandle(Z, function.ParameterNameAt(i))); | 402 dart::String::ZoneHandle(Z, function.ParameterNameAt(i)), |
| 403 AbstractType::dynamic_type()); |
| 357 scope_->InsertParameterAt(i, variable); | 404 scope_->InsertParameterAt(i, variable); |
| 358 } | 405 } |
| 359 break; | 406 break; |
| 360 case RawFunction::kSignatureFunction: | 407 case RawFunction::kSignatureFunction: |
| 361 case RawFunction::kIrregexpFunction: | 408 case RawFunction::kIrregexpFunction: |
| 362 UNREACHABLE(); | 409 UNREACHABLE(); |
| 363 } | 410 } |
| 364 | 411 |
| 365 parsed_function->AllocateVariables(); | 412 parsed_function->AllocateVariables(); |
| 366 | 413 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 VisitVariableDeclaration(node->variable()); | 568 VisitVariableDeclaration(node->variable()); |
| 522 node->body()->AcceptStatementVisitor(this); | 569 node->body()->AcceptStatementVisitor(this); |
| 523 ExitScope(); | 570 ExitScope(); |
| 524 --depth_.loop_; | 571 --depth_.loop_; |
| 525 --depth_.for_in_; | 572 --depth_.for_in_; |
| 526 } | 573 } |
| 527 | 574 |
| 528 | 575 |
| 529 void ScopeBuilder::AddSwitchVariable() { | 576 void ScopeBuilder::AddSwitchVariable() { |
| 530 if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) { | 577 if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) { |
| 531 LocalVariable* variable = MakeVariable(Symbols::SwitchExpr()); | 578 LocalVariable* variable = MakeVariable( |
| 579 Symbols::SwitchExpr(), |
| 580 AbstractType::dynamic_type()); |
| 532 variable->set_is_forced_stack(); | 581 variable->set_is_forced_stack(); |
| 533 current_function_scope_->AddVariable(variable); | 582 current_function_scope_->AddVariable(variable); |
| 534 result_->switch_variable = variable; | 583 result_->switch_variable = variable; |
| 535 } | 584 } |
| 536 } | 585 } |
| 537 | 586 |
| 538 | 587 |
| 539 void ScopeBuilder::VisitSwitchStatement(SwitchStatement* node) { | 588 void ScopeBuilder::VisitSwitchStatement(SwitchStatement* node) { |
| 540 AddSwitchVariable(); | 589 AddSwitchVariable(); |
| 541 node->VisitChildren(this); | 590 node->VisitChildren(this); |
| 542 } | 591 } |
| 543 | 592 |
| 544 | 593 |
| 545 void ScopeBuilder::VisitReturnStatement(ReturnStatement* node) { | 594 void ScopeBuilder::VisitReturnStatement(ReturnStatement* node) { |
| 546 if ((depth_.function_ == 0) && (depth_.finally_ > 0) && | 595 if ((depth_.function_ == 0) && (depth_.finally_ > 0) && |
| 547 (result_->finally_return_variable == NULL)) { | 596 (result_->finally_return_variable == NULL)) { |
| 548 const dart::String& name = H.DartSymbol(":try_finally_return_value"); | 597 const dart::String& name = H.DartSymbol(":try_finally_return_value"); |
| 549 LocalVariable* variable = MakeVariable(name); | 598 LocalVariable* variable = MakeVariable( |
| 599 name, |
| 600 AbstractType::dynamic_type()); |
| 550 current_function_scope_->AddVariable(variable); | 601 current_function_scope_->AddVariable(variable); |
| 551 result_->finally_return_variable = variable; | 602 result_->finally_return_variable = variable; |
| 552 } | 603 } |
| 553 node->VisitChildren(this); | 604 node->VisitChildren(this); |
| 554 } | 605 } |
| 555 | 606 |
| 556 | 607 |
| 557 void ScopeBuilder::VisitTryCatch(TryCatch* node) { | 608 void ScopeBuilder::VisitTryCatch(TryCatch* node) { |
| 558 ++depth_.try_; | 609 ++depth_.try_; |
| 559 AddTryVariables(); | 610 AddTryVariables(); |
| (...skipping 2164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2724 | 2775 |
| 2725 | 2776 |
| 2726 FlowGraph* FlowGraphBuilder::BuildGraph() { | 2777 FlowGraph* FlowGraphBuilder::BuildGraph() { |
| 2727 const dart::Function& function = parsed_function_->function(); | 2778 const dart::Function& function = parsed_function_->function(); |
| 2728 | 2779 |
| 2729 if (function.IsConstructorClosureFunction()) return NULL; | 2780 if (function.IsConstructorClosureFunction()) return NULL; |
| 2730 | 2781 |
| 2731 dart::Class& klass = | 2782 dart::Class& klass = |
| 2732 dart::Class::Handle(zone_, parsed_function_->function().Owner()); | 2783 dart::Class::Handle(zone_, parsed_function_->function().Owner()); |
| 2733 | 2784 |
| 2734 // Find out if there is an enclosing kernel class (which will be used to | 2785 Function& outermost_function = Function::Handle(Z); |
| 2735 // resolve type parameters). | 2786 TreeNode* outermost_node = NULL; |
| 2736 Class* kernel_klass = NULL; | 2787 Class* kernel_klass = NULL; |
| 2737 dart::Function& topmost = dart::Function::Handle(Z, function.raw()); | 2788 DiscoverEnclosingElements( |
| 2738 while (topmost.parent_function() != Object::null()) { | 2789 Z, function, &outermost_function, &outermost_node, &kernel_klass); |
| 2739 topmost = topmost.parent_function(); | |
| 2740 } | |
| 2741 TreeNode* topmost_node = static_cast<TreeNode*>(topmost.kernel_function()); | |
| 2742 if (topmost_node != NULL) { | |
| 2743 // Going up the closure->parent chain needs to result in a Procedure or | |
| 2744 // Constructor. | |
| 2745 TreeNode* parent = NULL; | |
| 2746 if (topmost_node->IsProcedure()) { | |
| 2747 parent = Procedure::Cast(topmost_node)->parent(); | |
| 2748 } else if (topmost_node->IsConstructor()) { | |
| 2749 parent = Constructor::Cast(topmost_node)->parent(); | |
| 2750 } else if (topmost_node->IsField()) { | |
| 2751 parent = Field::Cast(topmost_node)->parent(); | |
| 2752 } | |
| 2753 if (parent != NULL && parent->IsClass()) kernel_klass = Class::Cast(parent); | |
| 2754 } | |
| 2755 | 2790 |
| 2756 // Mark that we are using [klass]/[kernell_klass] as active class. Resolving | 2791 // Mark that we are using [klass]/[kernell_klass] as active class. Resolving |
| 2757 // of type parameters will get resolved via [kernell_klass] unless we are | 2792 // of type parameters will get resolved via [kernell_klass] unless we are |
| 2758 // nested inside a static factory in which case we will use [member]. | 2793 // nested inside a static factory in which case we will use [member]. |
| 2759 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass); | 2794 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass); |
| 2760 Member* member = topmost_node != NULL && topmost_node->IsMember() | 2795 Member* member = ((outermost_node != NULL) && outermost_node->IsMember()) |
| 2761 ? Member::Cast(topmost_node) | 2796 ? Member::Cast(outermost_node) |
| 2762 : NULL; | 2797 : NULL; |
| 2763 ActiveMemberScope active_member(&active_class_, member); | 2798 ActiveMemberScope active_member(&active_class_, member); |
| 2764 | 2799 |
| 2765 // The IR builder will create its own local variables and scopes, and it | 2800 // The IR builder will create its own local variables and scopes, and it |
| 2766 // will not need an AST. The code generator will assume that there is a | 2801 // will not need an AST. The code generator will assume that there is a |
| 2767 // local variable stack slot allocated for the current context and (I | 2802 // local variable stack slot allocated for the current context and (I |
| 2768 // think) that the runtime will expect it to be at a fixed offset which | 2803 // think) that the runtime will expect it to be at a fixed offset which |
| 2769 // requires allocating an unused expression temporary variable. | 2804 // requires allocating an unused expression temporary variable. |
| 2770 scopes_ = parsed_function_->EnsureKernelScopes(); | 2805 scopes_ = parsed_function_->EnsureKernelScopes(); |
| 2771 | 2806 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2839 LocalVariable* context = MakeTemporary(); | 2874 LocalVariable* context = MakeTemporary(); |
| 2840 | 2875 |
| 2841 // Copy captured parameters from the stack into the context. | 2876 // Copy captured parameters from the stack into the context. |
| 2842 LocalScope* scope = parsed_function_->node_sequence()->scope(); | 2877 LocalScope* scope = parsed_function_->node_sequence()->scope(); |
| 2843 intptr_t parameter_count = dart_function.NumParameters(); | 2878 intptr_t parameter_count = dart_function.NumParameters(); |
| 2844 intptr_t parameter_index = parsed_function_->first_parameter_index(); | 2879 intptr_t parameter_index = parsed_function_->first_parameter_index(); |
| 2845 for (intptr_t i = 0; i < parameter_count; ++i, --parameter_index) { | 2880 for (intptr_t i = 0; i < parameter_count; ++i, --parameter_index) { |
| 2846 LocalVariable* variable = scope->VariableAt(i); | 2881 LocalVariable* variable = scope->VariableAt(i); |
| 2847 if (variable->is_captured()) { | 2882 if (variable->is_captured()) { |
| 2848 // There is no LocalVariable describing the on-stack parameter so | 2883 // There is no LocalVariable describing the on-stack parameter so |
| 2849 // create one directly. | 2884 // create one directly and use the same type. |
| 2850 LocalVariable* parameter = | 2885 LocalVariable* parameter = |
| 2851 new (Z) LocalVariable(TokenPosition::kNoSource, | 2886 new (Z) LocalVariable(TokenPosition::kNoSource, |
| 2852 TokenPosition::kNoSource, | 2887 TokenPosition::kNoSource, |
| 2853 Symbols::TempParam(), | 2888 Symbols::TempParam(), |
| 2854 Object::dynamic_type()); | 2889 variable->type()); |
| 2855 parameter->set_index(parameter_index); | 2890 parameter->set_index(parameter_index); |
| 2856 // Mark the stack variable so it will be ignored by the code for | 2891 // Mark the stack variable so it will be ignored by the code for |
| 2857 // try/catch. | 2892 // try/catch. |
| 2858 parameter->set_is_captured_parameter(true); | 2893 parameter->set_is_captured_parameter(true); |
| 2859 | 2894 |
| 2860 // Copy the parameter from the stack to the context. Overwrite it | 2895 // Copy the parameter from the stack to the context. Overwrite it |
| 2861 // with a null constant on the stack so the original value is | 2896 // with a null constant on the stack so the original value is |
| 2862 // eligible for garbage collection. | 2897 // eligible for garbage collection. |
| 2863 body += LoadLocal(context); | 2898 body += LoadLocal(context); |
| 2864 body += LoadLocal(parameter); | 2899 body += LoadLocal(parameter); |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3797 bool saved_finalize = finalize_; | 3832 bool saved_finalize = finalize_; |
| 3798 finalize_ = false; | 3833 finalize_ = false; |
| 3799 H.SetFinalize(false); | 3834 H.SetFinalize(false); |
| 3800 AbstractType& result = TranslateType(node); | 3835 AbstractType& result = TranslateType(node); |
| 3801 finalize_ = saved_finalize; | 3836 finalize_ = saved_finalize; |
| 3802 H.SetFinalize(saved_finalize); | 3837 H.SetFinalize(saved_finalize); |
| 3803 return result; | 3838 return result; |
| 3804 } | 3839 } |
| 3805 | 3840 |
| 3806 | 3841 |
| 3842 const AbstractType& DartTypeTranslator::TranslateVariableType( |
| 3843 VariableDeclaration* variable) { |
| 3844 AbstractType& abstract_type = TranslateType(variable->type()); |
| 3845 |
| 3846 // We return a new `ZoneHandle` here on purpose: The intermediate language |
| 3847 // instructions do not make a copy of the handle, so we do it. |
| 3848 AbstractType& type = Type::ZoneHandle(Z); |
| 3849 |
| 3850 if (abstract_type.IsMalformed()) { |
| 3851 type = AbstractType::dynamic_type().raw(); |
| 3852 } else { |
| 3853 type = result_.raw(); |
| 3854 } |
| 3855 |
| 3856 return type; |
| 3857 } |
| 3858 |
| 3859 |
| 3807 void DartTypeTranslator::VisitInvalidType(InvalidType* node) { | 3860 void DartTypeTranslator::VisitInvalidType(InvalidType* node) { |
| 3808 result_ = ClassFinalizer::NewFinalizedMalformedType( | 3861 result_ = ClassFinalizer::NewFinalizedMalformedType( |
| 3809 Error::Handle(Z), // No previous error. | 3862 Error::Handle(Z), // No previous error. |
| 3810 dart::Script::Handle(Z, dart::Script::null()), TokenPosition::kNoSource, | 3863 dart::Script::Handle(Z, dart::Script::null()), TokenPosition::kNoSource, |
| 3811 "[InvalidType] in Kernel IR."); | 3864 "[InvalidType] in Kernel IR."); |
| 3812 } | 3865 } |
| 3813 | 3866 |
| 3814 | 3867 |
| 3815 void DartTypeTranslator::VisitFunctionType(FunctionType* node) { | 3868 void DartTypeTranslator::VisitFunctionType(FunctionType* node) { |
| 3816 // The spec describes in section "19.1 Static Types": | 3869 // The spec describes in section "19.1 Static Types": |
| (...skipping 1836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5653 instructions += LoadLocal(closure); | 5706 instructions += LoadLocal(closure); |
| 5654 instructions += LoadLocal(parsed_function_->current_context_var()); | 5707 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 5655 instructions += StoreInstanceField(Closure::context_offset()); | 5708 instructions += StoreInstanceField(Closure::context_offset()); |
| 5656 | 5709 |
| 5657 return instructions; | 5710 return instructions; |
| 5658 } | 5711 } |
| 5659 | 5712 |
| 5660 | 5713 |
| 5661 } // namespace kernel | 5714 } // namespace kernel |
| 5662 } // namespace dart | 5715 } // namespace dart |
| OLD | NEW |