| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1316 | 1316 |
| 1317 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1317 void EffectGraphVisitor::BuildTypecheckPushArguments( |
| 1318 intptr_t token_pos, | 1318 intptr_t token_pos, |
| 1319 PushArgumentInstr** push_instantiator_result, | 1319 PushArgumentInstr** push_instantiator_result, |
| 1320 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1320 PushArgumentInstr** push_instantiator_type_arguments_result) { |
| 1321 const Class& instantiator_class = Class::Handle( | 1321 const Class& instantiator_class = Class::Handle( |
| 1322 owner()->parsed_function()->function().Owner()); | 1322 owner()->parsed_function()->function().Owner()); |
| 1323 // Since called only when type tested against is not instantiated. | 1323 // Since called only when type tested against is not instantiated. |
| 1324 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1324 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 1325 Value* instantiator_type_arguments = NULL; | 1325 Value* instantiator_type_arguments = NULL; |
| 1326 Value* instantiator = BuildInstantiator(); | 1326 Value* instantiator = BuildInstantiator(instantiator_class); |
| 1327 if (instantiator == NULL) { | 1327 if (instantiator == NULL) { |
| 1328 // No instantiator when inside factory. | 1328 // No instantiator when inside factory. |
| 1329 *push_instantiator_result = PushArgument(BuildNullValue()); | 1329 *push_instantiator_result = PushArgument(BuildNullValue()); |
| 1330 instantiator_type_arguments = | 1330 instantiator_type_arguments = |
| 1331 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1331 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1332 } else { | 1332 } else { |
| 1333 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 1333 instantiator = Bind(BuildStoreExprTemp(instantiator)); |
| 1334 *push_instantiator_result = PushArgument(instantiator); | 1334 *push_instantiator_result = PushArgument(instantiator); |
| 1335 Value* loaded = Bind(BuildLoadExprTemp()); | 1335 Value* loaded = Bind(BuildLoadExprTemp()); |
| 1336 instantiator_type_arguments = | 1336 instantiator_type_arguments = |
| 1337 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); | 1337 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); |
| 1338 } | 1338 } |
| 1339 *push_instantiator_type_arguments_result = | 1339 *push_instantiator_type_arguments_result = |
| 1340 PushArgument(instantiator_type_arguments); | 1340 PushArgument(instantiator_type_arguments); |
| 1341 } | 1341 } |
| 1342 | 1342 |
| 1343 | 1343 |
| 1344 | 1344 |
| 1345 void EffectGraphVisitor::BuildTypecheckArguments( | 1345 void EffectGraphVisitor::BuildTypecheckArguments( |
| 1346 intptr_t token_pos, | 1346 intptr_t token_pos, |
| 1347 Value** instantiator_result, | 1347 Value** instantiator_result, |
| 1348 Value** instantiator_type_arguments_result) { | 1348 Value** instantiator_type_arguments_result) { |
| 1349 Value* instantiator = NULL; | 1349 Value* instantiator = NULL; |
| 1350 Value* instantiator_type_arguments = NULL; | 1350 Value* instantiator_type_arguments = NULL; |
| 1351 const Class& instantiator_class = Class::Handle( | 1351 const Class& instantiator_class = Class::Handle( |
| 1352 owner()->parsed_function()->function().Owner()); | 1352 owner()->parsed_function()->function().Owner()); |
| 1353 // Since called only when type tested against is not instantiated. | 1353 // Since called only when type tested against is not instantiated. |
| 1354 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1354 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 1355 instantiator = BuildInstantiator(); | 1355 instantiator = BuildInstantiator(instantiator_class); |
| 1356 if (instantiator == NULL) { | 1356 if (instantiator == NULL) { |
| 1357 // No instantiator when inside factory. | 1357 // No instantiator when inside factory. |
| 1358 instantiator = BuildNullValue(); | 1358 instantiator = BuildNullValue(); |
| 1359 instantiator_type_arguments = | 1359 instantiator_type_arguments = |
| 1360 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1360 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1361 } else { | 1361 } else { |
| 1362 // Preserve instantiator. | 1362 // Preserve instantiator. |
| 1363 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 1363 instantiator = Bind(BuildStoreExprTemp(instantiator)); |
| 1364 Value* loaded = Bind(BuildLoadExprTemp()); | 1364 Value* loaded = Bind(BuildLoadExprTemp()); |
| 1365 instantiator_type_arguments = | 1365 instantiator_type_arguments = |
| (...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2581 // t_n+1 <- ctor-arg | 2581 // t_n+1 <- ctor-arg |
| 2582 // t_n+2... <- constructor arguments start here | 2582 // t_n+2... <- constructor arguments start here |
| 2583 // StaticCall(constructor, t_n+1, t_n+2, ...) | 2583 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 2584 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2584 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 2585 Value* allocated_value = BuildObjectAllocation(node); | 2585 Value* allocated_value = BuildObjectAllocation(node); |
| 2586 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2586 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 2587 BuildConstructorCall(node, push_allocated_value); | 2587 BuildConstructorCall(node, push_allocated_value); |
| 2588 } | 2588 } |
| 2589 | 2589 |
| 2590 | 2590 |
| 2591 Value* EffectGraphVisitor::BuildInstantiator() { | 2591 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { |
| 2592 const Class& instantiator_class = Class::Handle( | 2592 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 2593 owner()->parsed_function()->function().Owner()); | |
| 2594 if (instantiator_class.NumTypeParameters() == 0) { | |
| 2595 return NULL; | |
| 2596 } | |
| 2597 Function& outer_function = | 2593 Function& outer_function = |
| 2598 Function::Handle(owner()->parsed_function()->function().raw()); | 2594 Function::Handle(owner()->parsed_function()->function().raw()); |
| 2599 while (outer_function.IsLocalFunction()) { | 2595 while (outer_function.IsLocalFunction()) { |
| 2600 outer_function = outer_function.parent_function(); | 2596 outer_function = outer_function.parent_function(); |
| 2601 } | 2597 } |
| 2602 if (outer_function.IsFactory()) { | 2598 if (outer_function.IsFactory()) { |
| 2603 return NULL; | 2599 return NULL; |
| 2604 } | 2600 } |
| 2605 | 2601 |
| 2606 ASSERT(owner()->parsed_function()->instantiator() != NULL); | 2602 LocalVariable* instantiator = owner()->parsed_function()->instantiator(); |
| 2607 ValueGraphVisitor for_instantiator(owner()); | 2603 ASSERT(instantiator != NULL); |
| 2608 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); | 2604 Value* result = Bind(BuildLoadLocal(*instantiator)); |
| 2609 Append(for_instantiator); | 2605 return result; |
| 2610 return for_instantiator.value(); | |
| 2611 } | 2606 } |
| 2612 | 2607 |
| 2613 | 2608 |
| 2614 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2609 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 2615 // is not NULL. | 2610 // is not NULL. |
| 2616 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2611 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2617 intptr_t token_pos, | 2612 intptr_t token_pos, |
| 2618 const Class& instantiator_class, | 2613 const Class& instantiator_class, |
| 2619 Value* instantiator) { | 2614 Value* instantiator) { |
| 2620 if (instantiator_class.NumTypeParameters() == 0) { | 2615 if (instantiator_class.NumTypeParameters() == 0) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2631 return Bind(new ConstantInstr(type_arguments)); | 2626 return Bind(new ConstantInstr(type_arguments)); |
| 2632 } | 2627 } |
| 2633 Function& outer_function = | 2628 Function& outer_function = |
| 2634 Function::Handle(owner()->parsed_function()->function().raw()); | 2629 Function::Handle(owner()->parsed_function()->function().raw()); |
| 2635 while (outer_function.IsLocalFunction()) { | 2630 while (outer_function.IsLocalFunction()) { |
| 2636 outer_function = outer_function.parent_function(); | 2631 outer_function = outer_function.parent_function(); |
| 2637 } | 2632 } |
| 2638 if (outer_function.IsFactory()) { | 2633 if (outer_function.IsFactory()) { |
| 2639 // No instantiator for factories. | 2634 // No instantiator for factories. |
| 2640 ASSERT(instantiator == NULL); | 2635 ASSERT(instantiator == NULL); |
| 2641 ASSERT(owner()->parsed_function()->instantiator() != NULL); | 2636 LocalVariable* instantiator_var = |
| 2642 ValueGraphVisitor for_instantiator(owner()); | 2637 owner()->parsed_function()->instantiator(); |
| 2643 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); | 2638 ASSERT(instantiator_var != NULL); |
| 2644 Append(for_instantiator); | 2639 return Bind(BuildLoadLocal(*instantiator_var)); |
| 2645 return for_instantiator.value(); | |
| 2646 } | 2640 } |
| 2647 if (instantiator == NULL) { | 2641 if (instantiator == NULL) { |
| 2648 instantiator = BuildInstantiator(); | 2642 instantiator = BuildInstantiator(instantiator_class); |
| 2649 } | 2643 } |
| 2650 // The instantiator is the receiver of the caller, which is not a factory. | 2644 // The instantiator is the receiver of the caller, which is not a factory. |
| 2651 // The receiver cannot be null; extract its TypeArguments object. | 2645 // The receiver cannot be null; extract its TypeArguments object. |
| 2652 // Note that in the factory case, the instantiator is the first parameter | 2646 // Note that in the factory case, the instantiator is the first parameter |
| 2653 // of the factory, i.e. already a TypeArguments object. | 2647 // of the factory, i.e. already a TypeArguments object. |
| 2654 intptr_t type_arguments_field_offset = | 2648 intptr_t type_arguments_field_offset = |
| 2655 instantiator_class.type_arguments_field_offset(); | 2649 instantiator_class.type_arguments_field_offset(); |
| 2656 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); | 2650 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); |
| 2657 | 2651 |
| 2658 return Bind(new LoadFieldInstr( | 2652 return Bind(new LoadFieldInstr( |
| (...skipping 1276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3935 function.token_pos(), | 3929 function.token_pos(), |
| 3936 LanguageError::kError, | 3930 LanguageError::kError, |
| 3937 Heap::kNew, | 3931 Heap::kNew, |
| 3938 "FlowGraphBuilder Bailout: %s %s", | 3932 "FlowGraphBuilder Bailout: %s %s", |
| 3939 String::Handle(function.name()).ToCString(), | 3933 String::Handle(function.name()).ToCString(), |
| 3940 reason)); | 3934 reason)); |
| 3941 Isolate::Current()->long_jump_base()->Jump(1, error); | 3935 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3942 } | 3936 } |
| 3943 | 3937 |
| 3944 } // namespace dart | 3938 } // namespace dart |
| OLD | NEW |