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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 ReturnDefinition(call); | 1505 ReturnDefinition(call); |
1506 } | 1506 } |
1507 | 1507 |
1508 | 1508 |
1509 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1509 void EffectGraphVisitor::BuildTypecheckPushArguments( |
1510 intptr_t token_pos, | 1510 intptr_t token_pos, |
1511 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1511 PushArgumentInstr** push_instantiator_type_arguments_result) { |
1512 const Class& instantiator_class = Class::Handle( | 1512 const Class& instantiator_class = Class::Handle( |
1513 Z, owner()->function().Owner()); | 1513 Z, owner()->function().Owner()); |
1514 // Since called only when type tested against is not instantiated. | 1514 // Since called only when type tested against is not instantiated. |
1515 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1515 ASSERT(instantiator_class.IsGeneric()); |
1516 Value* instantiator_type_arguments = NULL; | 1516 Value* instantiator_type_arguments = NULL; |
1517 Value* instantiator = BuildInstantiator(token_pos, instantiator_class); | 1517 Value* instantiator = BuildInstantiator(token_pos, instantiator_class); |
1518 if (instantiator == NULL) { | 1518 if (instantiator == NULL) { |
1519 // No instantiator when inside factory. | 1519 // No instantiator when inside factory. |
1520 instantiator_type_arguments = | 1520 instantiator_type_arguments = |
1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
1522 } else { | 1522 } else { |
1523 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1523 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
1524 token_pos, instantiator_class, instantiator); | 1524 token_pos, instantiator_class, instantiator); |
1525 } | 1525 } |
1526 *push_instantiator_type_arguments_result = | 1526 *push_instantiator_type_arguments_result = |
1527 PushArgument(instantiator_type_arguments); | 1527 PushArgument(instantiator_type_arguments); |
1528 } | 1528 } |
1529 | 1529 |
1530 | 1530 |
1531 | 1531 |
1532 void EffectGraphVisitor::BuildTypecheckArguments( | 1532 void EffectGraphVisitor::BuildTypecheckArguments( |
1533 intptr_t token_pos, | 1533 intptr_t token_pos, |
1534 Value** instantiator_type_arguments_result) { | 1534 Value** instantiator_type_arguments_result) { |
1535 Value* instantiator = NULL; | 1535 Value* instantiator = NULL; |
1536 Value* instantiator_type_arguments = NULL; | 1536 Value* instantiator_type_arguments = NULL; |
1537 const Class& instantiator_class = Class::Handle( | 1537 const Class& instantiator_class = Class::Handle( |
1538 Z, owner()->function().Owner()); | 1538 Z, owner()->function().Owner()); |
1539 // Since called only when type tested against is not instantiated. | 1539 // Since called only when type tested against is not instantiated. |
1540 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1540 ASSERT(instantiator_class.IsGeneric()); |
1541 instantiator = BuildInstantiator(token_pos, instantiator_class); | 1541 instantiator = BuildInstantiator(token_pos, instantiator_class); |
1542 if (instantiator == NULL) { | 1542 if (instantiator == NULL) { |
1543 // No instantiator when inside factory. | 1543 // No instantiator when inside factory. |
1544 instantiator_type_arguments = | 1544 instantiator_type_arguments = |
1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
1546 } else { | 1546 } else { |
1547 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1547 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
1548 token_pos, instantiator_class, instantiator); | 1548 token_pos, instantiator_class, instantiator); |
1549 } | 1549 } |
1550 *instantiator_type_arguments_result = instantiator_type_arguments; | 1550 *instantiator_type_arguments_result = instantiator_type_arguments; |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 // finally clauses. If we already have a function object for the | 2511 // finally clauses. If we already have a function object for the |
2512 // same closure, do not add a second one. We compare token position, | 2512 // same closure, do not add a second one. We compare token position, |
2513 // and parent function to detect duplicates. | 2513 // and parent function to detect duplicates. |
2514 const Function& parent = Function::Handle(function.parent_function()); | 2514 const Function& parent = Function::Handle(function.parent_function()); |
2515 const Function& found_func = Function::Handle(Z, | 2515 const Function& found_func = Function::Handle(Z, |
2516 isolate()->LookupClosureFunction(parent, function.token_pos())); | 2516 isolate()->LookupClosureFunction(parent, function.token_pos())); |
2517 if (found_func.IsNull()) { | 2517 if (found_func.IsNull()) { |
2518 isolate()->AddClosureFunction(function); | 2518 isolate()->AddClosureFunction(function); |
2519 } | 2519 } |
2520 } | 2520 } |
2521 ZoneGrowableArray<PushArgumentInstr*>* arguments = | |
2522 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); | |
2523 ASSERT(function.context_scope() != ContextScope::null()); | 2521 ASSERT(function.context_scope() != ContextScope::null()); |
2524 | 2522 |
2525 // The function type of a closure may have type arguments. In that case, | 2523 // The function type of a closure may have type arguments. In that case, |
2526 // pass the type arguments of the instantiator. | 2524 // pass the type arguments of the instantiator. |
2527 const Class& cls = Class::ZoneHandle(Z, function.signature_class()); | 2525 const Class& closure_class = |
2528 ASSERT(!cls.IsNull()); | 2526 Class::ZoneHandle(Z, isolate()->object_store()->closure_class()); |
2529 const bool requires_type_arguments = cls.NumTypeArguments() > 0; | 2527 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = |
2530 Value* type_arguments = NULL; | 2528 new(Z) ZoneGrowableArray<PushArgumentInstr*>(0); |
2531 if (requires_type_arguments) { | |
2532 ASSERT(cls.type_arguments_field_offset() == | |
2533 Closure::type_arguments_offset()); | |
2534 ASSERT(cls.instance_size() == Closure::InstanceSize()); | |
2535 const Class& instantiator_class = Class::Handle( | |
2536 Z, owner()->function().Owner()); | |
2537 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | |
2538 instantiator_class, | |
2539 NULL); | |
2540 arguments->Add(PushArgument(type_arguments)); | |
2541 } | |
2542 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), | 2529 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), |
2543 cls, | 2530 closure_class, |
2544 arguments); | 2531 no_arguments); |
2545 alloc->set_closure_function(function); | 2532 alloc->set_closure_function(function); |
2546 | 2533 |
2547 Value* closure_val = Bind(alloc); | 2534 Value* closure_val = Bind(alloc); |
2548 { LocalVariable* closure_tmp_var = | 2535 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val, |
2549 EnterTempLocalScope(closure_val, node->token_pos()); | 2536 node->token_pos()); |
| 2537 // Store type arguments if scope class is generic. |
| 2538 const FunctionType& function_type = |
| 2539 FunctionType::ZoneHandle(Z, function.SignatureType()); |
| 2540 const Class& scope_cls = Class::ZoneHandle(Z, function_type.scope_class()); |
| 2541 if (scope_cls.IsGeneric()) { |
| 2542 ASSERT(function.Owner() == scope_cls.raw()); |
| 2543 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var, |
| 2544 node->token_pos())); |
| 2545 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 2546 scope_cls, |
| 2547 NULL); |
| 2548 Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(), |
| 2549 closure_tmp_val, |
| 2550 type_arguments, |
| 2551 kEmitStoreBarrier, |
| 2552 node->token_pos())); |
| 2553 } |
| 2554 |
2550 // Store function. | 2555 // Store function. |
2551 Value* closure_tmp_val = | 2556 Value* closure_tmp_val = |
2552 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); | 2557 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
2553 Value* func_val = | 2558 Value* func_val = |
2554 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); | 2559 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); |
2555 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(), | 2560 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(), |
2556 closure_tmp_val, | 2561 closure_tmp_val, |
2557 func_val, | 2562 func_val, |
2558 kEmitStoreBarrier, | 2563 kEmitStoreBarrier, |
2559 node->token_pos())); | 2564 node->token_pos())); |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2906 // StaticCall(constructor, t_n+1, t_n+2, ...) | 2911 // StaticCall(constructor, t_n+1, t_n+2, ...) |
2907 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2912 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
2908 Value* allocated_value = BuildObjectAllocation(node); | 2913 Value* allocated_value = BuildObjectAllocation(node); |
2909 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2914 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
2910 BuildConstructorCall(node, push_allocated_value); | 2915 BuildConstructorCall(node, push_allocated_value); |
2911 } | 2916 } |
2912 | 2917 |
2913 | 2918 |
2914 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos, | 2919 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos, |
2915 const Class& instantiator_class) { | 2920 const Class& instantiator_class) { |
2916 ASSERT(instantiator_class.NumTypeParameters() > 0); | 2921 ASSERT(instantiator_class.IsGeneric()); |
2917 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2922 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
2918 while (outer_function.IsLocalFunction()) { | 2923 while (outer_function.IsLocalFunction()) { |
2919 outer_function = outer_function.parent_function(); | 2924 outer_function = outer_function.parent_function(); |
2920 } | 2925 } |
2921 if (outer_function.IsFactory()) { | 2926 if (outer_function.IsFactory()) { |
2922 return NULL; | 2927 return NULL; |
2923 } | 2928 } |
2924 | 2929 |
2925 LocalVariable* instantiator = owner()->parsed_function().instantiator(); | 2930 LocalVariable* instantiator = owner()->parsed_function().instantiator(); |
2926 ASSERT(instantiator != NULL); | 2931 ASSERT(instantiator != NULL); |
(...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4452 | 4457 |
4453 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( | 4458 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( |
4454 intptr_t token_pos, | 4459 intptr_t token_pos, |
4455 const Class& function_class, | 4460 const Class& function_class, |
4456 const String& function_name, | 4461 const String& function_name, |
4457 ArgumentListNode* function_arguments, | 4462 ArgumentListNode* function_arguments, |
4458 int invocation_type) { | 4463 int invocation_type) { |
4459 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 4464 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
4460 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); | 4465 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); |
4461 // Object receiver, actually a class literal of the unresolved method's owner. | 4466 // Object receiver, actually a class literal of the unresolved method's owner. |
4462 Type& type = Type::ZoneHandle( | 4467 AbstractType& type = Type::ZoneHandle( |
4463 Z, | 4468 Z, |
4464 Type::New(function_class, | 4469 Type::New(function_class, |
4465 TypeArguments::Handle(Z, TypeArguments::null()), | 4470 TypeArguments::Handle(Z, TypeArguments::null()), |
4466 token_pos, | 4471 token_pos, |
4467 Heap::kOld)); | 4472 Heap::kOld)); |
4468 type ^= ClassFinalizer::FinalizeType( | 4473 type ^= ClassFinalizer::FinalizeType( |
4469 function_class, type, ClassFinalizer::kCanonicalize); | 4474 function_class, type, ClassFinalizer::kCanonicalize); |
4470 Value* receiver_value = Bind(new(Z) ConstantInstr(type)); | 4475 Value* receiver_value = Bind(new(Z) ConstantInstr(type)); |
4471 arguments->Add(PushArgument(receiver_value)); | 4476 arguments->Add(PushArgument(receiver_value)); |
4472 // String memberName. | 4477 // String memberName. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4661 Script::Handle(function.script()), | 4666 Script::Handle(function.script()), |
4662 function.token_pos(), | 4667 function.token_pos(), |
4663 Report::AtLocation, | 4668 Report::AtLocation, |
4664 "FlowGraphBuilder Bailout: %s %s", | 4669 "FlowGraphBuilder Bailout: %s %s", |
4665 String::Handle(function.name()).ToCString(), | 4670 String::Handle(function.name()).ToCString(), |
4666 reason); | 4671 reason); |
4667 UNREACHABLE(); | 4672 UNREACHABLE(); |
4668 } | 4673 } |
4669 | 4674 |
4670 } // namespace dart | 4675 } // namespace dart |
OLD | NEW |