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