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 |