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 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 ReturnDefinition(call); | 1495 ReturnDefinition(call); |
1496 } | 1496 } |
1497 | 1497 |
1498 | 1498 |
1499 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1499 void EffectGraphVisitor::BuildTypecheckPushArguments( |
1500 intptr_t token_pos, | 1500 intptr_t token_pos, |
1501 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1501 PushArgumentInstr** push_instantiator_type_arguments_result) { |
1502 const Class& instantiator_class = Class::Handle( | 1502 const Class& instantiator_class = Class::Handle( |
1503 Z, owner()->function().Owner()); | 1503 Z, owner()->function().Owner()); |
1504 // Since called only when type tested against is not instantiated. | 1504 // Since called only when type tested against is not instantiated. |
1505 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1505 ASSERT(instantiator_class.IsGeneric()); |
1506 Value* instantiator_type_arguments = NULL; | 1506 Value* instantiator_type_arguments = NULL; |
1507 Value* instantiator = BuildInstantiator(instantiator_class); | 1507 Value* instantiator = BuildInstantiator(instantiator_class); |
1508 if (instantiator == NULL) { | 1508 if (instantiator == NULL) { |
1509 // No instantiator when inside factory. | 1509 // No instantiator when inside factory. |
1510 instantiator_type_arguments = | 1510 instantiator_type_arguments = |
1511 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1511 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
1512 } else { | 1512 } else { |
1513 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1513 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
1514 token_pos, instantiator_class, instantiator); | 1514 token_pos, instantiator_class, instantiator); |
1515 } | 1515 } |
1516 *push_instantiator_type_arguments_result = | 1516 *push_instantiator_type_arguments_result = |
1517 PushArgument(instantiator_type_arguments); | 1517 PushArgument(instantiator_type_arguments); |
1518 } | 1518 } |
1519 | 1519 |
1520 | 1520 |
1521 | 1521 |
1522 void EffectGraphVisitor::BuildTypecheckArguments( | 1522 void EffectGraphVisitor::BuildTypecheckArguments( |
1523 intptr_t token_pos, | 1523 intptr_t token_pos, |
1524 Value** instantiator_type_arguments_result) { | 1524 Value** instantiator_type_arguments_result) { |
1525 Value* instantiator = NULL; | 1525 Value* instantiator = NULL; |
1526 Value* instantiator_type_arguments = NULL; | 1526 Value* instantiator_type_arguments = NULL; |
1527 const Class& instantiator_class = Class::Handle( | 1527 const Class& instantiator_class = Class::Handle( |
1528 Z, owner()->function().Owner()); | 1528 Z, owner()->function().Owner()); |
1529 // Since called only when type tested against is not instantiated. | 1529 // Since called only when type tested against is not instantiated. |
1530 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1530 ASSERT(instantiator_class.IsGeneric()); |
1531 instantiator = BuildInstantiator(instantiator_class); | 1531 instantiator = BuildInstantiator(instantiator_class); |
1532 if (instantiator == NULL) { | 1532 if (instantiator == NULL) { |
1533 // No instantiator when inside factory. | 1533 // No instantiator when inside factory. |
1534 instantiator_type_arguments = | 1534 instantiator_type_arguments = |
1535 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1535 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
1536 } else { | 1536 } else { |
1537 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1537 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
1538 token_pos, instantiator_class, instantiator); | 1538 token_pos, instantiator_class, instantiator); |
1539 } | 1539 } |
1540 *instantiator_type_arguments_result = instantiator_type_arguments; | 1540 *instantiator_type_arguments_result = instantiator_type_arguments; |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2493 // finally clauses. If we already have a function object for the | 2493 // finally clauses. If we already have a function object for the |
2494 // same closure, do not add a second one. We compare token position, | 2494 // same closure, do not add a second one. We compare token position, |
2495 // and parent function to detect duplicates. | 2495 // and parent function to detect duplicates. |
2496 const Function& parent = Function::Handle(function.parent_function()); | 2496 const Function& parent = Function::Handle(function.parent_function()); |
2497 const Function& found_func = Function::Handle(Z, | 2497 const Function& found_func = Function::Handle(Z, |
2498 isolate()->LookupClosureFunction(parent, function.token_pos())); | 2498 isolate()->LookupClosureFunction(parent, function.token_pos())); |
2499 if (found_func.IsNull()) { | 2499 if (found_func.IsNull()) { |
2500 isolate()->AddClosureFunction(function); | 2500 isolate()->AddClosureFunction(function); |
2501 } | 2501 } |
2502 } | 2502 } |
2503 ZoneGrowableArray<PushArgumentInstr*>* arguments = | |
2504 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); | |
2505 ASSERT(function.context_scope() != ContextScope::null()); | 2503 ASSERT(function.context_scope() != ContextScope::null()); |
2506 | 2504 |
2507 // The function type of a closure may have type arguments. In that case, | 2505 // The function type of a closure may have type arguments. In that case, |
2508 // pass the type arguments of the instantiator. | 2506 // pass the type arguments of the instantiator. |
2509 const Class& cls = Class::ZoneHandle(Z, function.signature_class()); | 2507 const Class& closure_class = |
2510 ASSERT(!cls.IsNull()); | 2508 Class::ZoneHandle(Z, isolate()->object_store()->closure_class()); |
2511 const bool requires_type_arguments = cls.NumTypeArguments() > 0; | 2509 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = |
2512 Value* type_arguments = NULL; | 2510 new(Z) ZoneGrowableArray<PushArgumentInstr*>(0); |
2513 if (requires_type_arguments) { | |
2514 ASSERT(cls.type_arguments_field_offset() == | |
2515 Closure::type_arguments_offset()); | |
2516 ASSERT(cls.instance_size() == Closure::InstanceSize()); | |
2517 const Class& instantiator_class = Class::Handle( | |
2518 Z, owner()->function().Owner()); | |
2519 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | |
2520 instantiator_class, | |
2521 NULL); | |
2522 arguments->Add(PushArgument(type_arguments)); | |
2523 } | |
2524 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), | 2511 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), |
2525 cls, | 2512 closure_class, |
2526 arguments); | 2513 no_arguments); |
2527 alloc->set_closure_function(function); | 2514 alloc->set_closure_function(function); |
2528 | 2515 |
2529 Value* closure_val = Bind(alloc); | 2516 Value* closure_val = Bind(alloc); |
2530 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); | 2517 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); |
| 2518 // Store type arguments if scope class is generic. |
| 2519 const FunctionType& function_type = |
| 2520 FunctionType::ZoneHandle(Z, function.SignatureType()); |
| 2521 const Class& scope_cls = Class::ZoneHandle(Z, function_type.scope_class()); |
| 2522 if (scope_cls.IsGeneric()) { |
| 2523 ASSERT(function.Owner() == scope_cls.raw()); |
| 2524 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var)); |
| 2525 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 2526 scope_cls, |
| 2527 NULL); |
| 2528 Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(), |
| 2529 closure_tmp_val, |
| 2530 type_arguments, |
| 2531 kEmitStoreBarrier, |
| 2532 node->token_pos())); |
| 2533 } |
| 2534 |
2531 // Store function. | 2535 // Store function. |
2532 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var)); | 2536 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var)); |
2533 Value* func_val = | 2537 Value* func_val = |
2534 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); | 2538 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); |
2535 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(), | 2539 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(), |
2536 closure_tmp_val, | 2540 closure_tmp_val, |
2537 func_val, | 2541 func_val, |
2538 kEmitStoreBarrier, | 2542 kEmitStoreBarrier, |
2539 node->token_pos())); | 2543 node->token_pos())); |
2540 if (is_implicit) { | 2544 if (is_implicit) { |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2880 // t_n+2... <- constructor arguments start here | 2884 // t_n+2... <- constructor arguments start here |
2881 // StaticCall(constructor, t_n+1, t_n+2, ...) | 2885 // StaticCall(constructor, t_n+1, t_n+2, ...) |
2882 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2886 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
2883 Value* allocated_value = BuildObjectAllocation(node); | 2887 Value* allocated_value = BuildObjectAllocation(node); |
2884 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2888 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
2885 BuildConstructorCall(node, push_allocated_value); | 2889 BuildConstructorCall(node, push_allocated_value); |
2886 } | 2890 } |
2887 | 2891 |
2888 | 2892 |
2889 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { | 2893 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { |
2890 ASSERT(instantiator_class.NumTypeParameters() > 0); | 2894 ASSERT(instantiator_class.IsGeneric()); |
2891 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2895 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
2892 while (outer_function.IsLocalFunction()) { | 2896 while (outer_function.IsLocalFunction()) { |
2893 outer_function = outer_function.parent_function(); | 2897 outer_function = outer_function.parent_function(); |
2894 } | 2898 } |
2895 if (outer_function.IsFactory()) { | 2899 if (outer_function.IsFactory()) { |
2896 return NULL; | 2900 return NULL; |
2897 } | 2901 } |
2898 | 2902 |
2899 LocalVariable* instantiator = owner()->parsed_function().instantiator(); | 2903 LocalVariable* instantiator = owner()->parsed_function().instantiator(); |
2900 ASSERT(instantiator != NULL); | 2904 ASSERT(instantiator != NULL); |
(...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4413 | 4417 |
4414 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( | 4418 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( |
4415 intptr_t token_pos, | 4419 intptr_t token_pos, |
4416 const Class& function_class, | 4420 const Class& function_class, |
4417 const String& function_name, | 4421 const String& function_name, |
4418 ArgumentListNode* function_arguments, | 4422 ArgumentListNode* function_arguments, |
4419 int invocation_type) { | 4423 int invocation_type) { |
4420 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 4424 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
4421 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); | 4425 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); |
4422 // Object receiver, actually a class literal of the unresolved method's owner. | 4426 // Object receiver, actually a class literal of the unresolved method's owner. |
4423 Type& type = Type::ZoneHandle( | 4427 AbstractType& type = Type::ZoneHandle( |
4424 Z, | 4428 Z, |
4425 Type::New(function_class, | 4429 Type::New(function_class, |
4426 TypeArguments::Handle(Z, TypeArguments::null()), | 4430 TypeArguments::Handle(Z, TypeArguments::null()), |
4427 token_pos, | 4431 token_pos, |
4428 Heap::kOld)); | 4432 Heap::kOld)); |
4429 type ^= ClassFinalizer::FinalizeType( | 4433 type ^= ClassFinalizer::FinalizeType( |
4430 function_class, type, ClassFinalizer::kCanonicalize); | 4434 function_class, type, ClassFinalizer::kCanonicalize); |
4431 Value* receiver_value = Bind(new(Z) ConstantInstr(type)); | 4435 Value* receiver_value = Bind(new(Z) ConstantInstr(type)); |
4432 arguments->Add(PushArgument(receiver_value)); | 4436 arguments->Add(PushArgument(receiver_value)); |
4433 // String memberName. | 4437 // String memberName. |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4621 Report::MessageF(Report::kBailout, | 4625 Report::MessageF(Report::kBailout, |
4622 Script::Handle(function.script()), | 4626 Script::Handle(function.script()), |
4623 function.token_pos(), | 4627 function.token_pos(), |
4624 "FlowGraphBuilder Bailout: %s %s", | 4628 "FlowGraphBuilder Bailout: %s %s", |
4625 String::Handle(function.name()).ToCString(), | 4629 String::Handle(function.name()).ToCString(), |
4626 reason); | 4630 reason); |
4627 UNREACHABLE(); | 4631 UNREACHABLE(); |
4628 } | 4632 } |
4629 | 4633 |
4630 } // namespace dart | 4634 } // namespace dart |
OLD | NEW |