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. | |
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 = | |
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 | |
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() | |
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()); | |
kustermann
2016/11/03 13:09:31
I guess for all synthetic [LocalVariable]s we can
| |
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() |
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 |