OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/hash_table.h" | 9 #include "vm/hash_table.h" |
10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 for (intptr_t i = 0; i < num_arguments; i++) { | 559 for (intptr_t i = 0; i < num_arguments; i++) { |
560 type_argument = arguments.TypeAt(i); | 560 type_argument = arguments.TypeAt(i); |
561 ResolveType(cls, type_argument); | 561 ResolveType(cls, type_argument); |
562 } | 562 } |
563 } | 563 } |
564 // Resolve signature if function type. | 564 // Resolve signature if function type. |
565 if (type.IsFunctionType()) { | 565 if (type.IsFunctionType()) { |
566 const Function& signature = Function::Handle(Type::Cast(type).signature()); | 566 const Function& signature = Function::Handle(Type::Cast(type).signature()); |
567 Type& signature_type = Type::Handle(signature.SignatureType()); | 567 Type& signature_type = Type::Handle(signature.SignatureType()); |
568 if (signature_type.raw() != type.raw()) { | 568 if (signature_type.raw() != type.raw()) { |
| 569 // This type was promoted to a function type because its type class is a |
| 570 // typedef class. The promotion is achieved by assigning the signature |
| 571 // function of the typedef class to this type. This function is pointing |
| 572 // to the original typedef function type, which is not this type. |
| 573 // By resolving the typedef function type (which may already be resolved, |
| 574 // hence saving work), we will resolve the shared signature function. |
| 575 ASSERT(Class::Handle(type.type_class()).IsTypedefClass()); |
569 ResolveType(cls, signature_type); | 576 ResolveType(cls, signature_type); |
570 } else { | 577 } else { |
571 const Class& scope_class = Class::Handle(type.type_class()); | 578 const Class& scope_class = Class::Handle(type.type_class()); |
572 if (scope_class.IsTypedefClass()) { | 579 if (scope_class.IsTypedefClass()) { |
| 580 // This type is the original function type of the typedef class. |
573 ResolveSignature(scope_class, signature); | 581 ResolveSignature(scope_class, signature); |
574 } else { | 582 } else { |
| 583 ASSERT(scope_class.IsClosureClass()); |
575 ResolveSignature(cls, signature); | 584 ResolveSignature(cls, signature); |
576 if ((type.arguments() != TypeArguments::null()) && | 585 ASSERT(type.arguments() == TypeArguments::null()); |
577 signature.HasInstantiatedSignature()) { | 586 if (signature.IsSignatureFunction()) { |
578 ASSERT(scope_class.IsGeneric()); | 587 // Drop fields that are not necessary anymore after resolution. |
579 // Although the scope class of this function type is generic, | 588 // The parent function, owner, and token position of a shared |
580 // the signature of this function type does not refer to any | 589 // canonical function type are meaningless, since the canonical |
581 // of its type parameters. Reset its scope class to _Closure. | 590 // representent is picked arbitrarily. |
582 Type::Cast(type).set_type_class(Class::Handle( | 591 signature.set_parent_function(Function::Handle()); |
583 Isolate::Current()->object_store()->closure_class())); | 592 // TODO(regis): As long as we support metadata in typedef signatures, |
584 type.set_arguments(Object::null_type_arguments()); | 593 // we cannot reset these fields used to reparse a typedef. |
585 } | 594 // Note that the scope class of a typedef function type is always |
586 } | 595 // preserved as the typedef class (not reset to _Closure class), |
587 if (signature.IsSignatureFunction()) { | 596 // thereby preventing sharing of canonical function types between |
588 // Drop fields that are not necessary anymore after resolution. | 597 // typedefs. Not being shared, these fields are therefore always |
589 // The parent function, owner, and token position of a shared | 598 // meaningful for typedefs. |
590 // canonical function type are meaningless, since the canonical | 599 if (!scope_class.IsTypedefClass()) { |
591 // representent is picked arbitrarily. | 600 signature.set_owner(Object::Handle()); |
592 signature.set_parent_function(Function::Handle()); | 601 signature.set_token_pos(TokenPosition::kNoSource); |
593 // TODO(regis): As long as we support metadata in typedef signatures, | 602 } |
594 // we cannot reset these fields used to reparse a typedef. | |
595 // Note that the scope class of a typedef function type is always | |
596 // preserved as the typedef class (not reset to _Closure class), thereby | |
597 // preventing sharing of canonical function types between typedefs. | |
598 // Not being shared, these fields are therefore always meaningful for | |
599 // typedefs. | |
600 if (!scope_class.IsTypedefClass()) { | |
601 signature.set_owner(Object::Handle()); | |
602 signature.set_token_pos(TokenPosition::kNoSource); | |
603 } | 603 } |
604 } | 604 } |
605 } | 605 } |
606 } | 606 } |
607 } | 607 } |
608 | 608 |
609 | 609 |
610 void ClassFinalizer::FinalizeTypeParameters(const Class& cls, | 610 void ClassFinalizer::FinalizeTypeParameters(const Class& cls, |
611 PendingTypes* pending_types) { | 611 PendingTypes* pending_types) { |
612 if (FLAG_trace_type_finalization) { | 612 if (FLAG_trace_type_finalization) { |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 ASSERT(num_super_type_args == | 884 ASSERT(num_super_type_args == |
885 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); | 885 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); |
886 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { | 886 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { |
887 super_type ^= FinalizeType(cls, super_type, kFinalize, pending_types); | 887 super_type ^= FinalizeType(cls, super_type, kFinalize, pending_types); |
888 cls.set_super_type(super_type); | 888 cls.set_super_type(super_type); |
889 } | 889 } |
890 TypeArguments& super_type_args = | 890 TypeArguments& super_type_args = |
891 TypeArguments::Handle(super_type.arguments()); | 891 TypeArguments::Handle(super_type.arguments()); |
892 // Offset of super type's type parameters in cls' type argument vector. | 892 // Offset of super type's type parameters in cls' type argument vector. |
893 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 893 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
| 894 // If the super type is raw (i.e. super_type_args is null), set to dynamic. |
894 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 895 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
895 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 896 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
896 if (!super_type_args.IsNull()) { | 897 if (!super_type_args.IsNull()) { |
897 super_type_arg = super_type_args.TypeAt(i); | 898 super_type_arg = super_type_args.TypeAt(i); |
898 if (!super_type_arg.IsTypeRef()) { | 899 if (!super_type_arg.IsTypeRef()) { |
899 if (super_type_arg.IsBeingFinalized()) { | 900 if (super_type_arg.IsBeingFinalized()) { |
900 ASSERT(super_type_arg.IsType()); | 901 ASSERT(super_type_arg.IsType()); |
901 CheckRecursiveType(cls, super_type_arg, pending_types); | 902 CheckRecursiveType(cls, super_type_arg, pending_types); |
902 if (FLAG_trace_type_finalization) { | 903 if (FLAG_trace_type_finalization) { |
903 THR_Print("Creating TypeRef '%s': '%s'\n", | 904 THR_Print("Creating TypeRef '%s': '%s'\n", |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 if (!type.IsMalformed() && !type.IsCanonical()) { | 1233 if (!type.IsMalformed() && !type.IsCanonical()) { |
1233 CheckTypeBounds(cls, type); | 1234 CheckTypeBounds(cls, type); |
1234 } | 1235 } |
1235 } | 1236 } |
1236 } | 1237 } |
1237 | 1238 |
1238 // If the type is a function type, we also need to finalize the types in its | 1239 // If the type is a function type, we also need to finalize the types in its |
1239 // signature, i.e. finalize the result type and parameter types of the | 1240 // signature, i.e. finalize the result type and parameter types of the |
1240 // signature function of this function type. | 1241 // signature function of this function type. |
1241 // We do this after marking this type as finalized in order to allow a | 1242 // We do this after marking this type as finalized in order to allow a |
1242 // function type to refer to itself via its parameter types and result type. | 1243 // typedef function type to refer to itself via its parameter types and |
1243 // Note that we do not instantiate these types according to the type | 1244 // result type. |
1244 // arguments. This will happen on demand when executing a type test. | |
1245 if (type.IsFunctionType()) { | 1245 if (type.IsFunctionType()) { |
1246 const Function& signature = | 1246 ASSERT(!type.IsBeingFinalized()); |
1247 Function::Handle(zone, Type::Cast(type).signature()); | 1247 const Type& fun_type = Type::Cast(type); |
1248 const Class& scope_class = | 1248 const Class& scope_class = Class::Handle(zone, fun_type.type_class()); |
1249 Class::Handle(zone, Type::Cast(type).type_class()); | |
1250 if (scope_class.IsTypedefClass()) { | 1249 if (scope_class.IsTypedefClass()) { |
1251 FinalizeSignature(scope_class, signature); | 1250 Function& signature = |
| 1251 Function::Handle(zone, scope_class.signature_function()); |
| 1252 if (!scope_class.is_type_finalized()) { |
| 1253 FinalizeSignature(scope_class, signature); |
| 1254 } |
| 1255 // If the function type is a generic typedef, instantiate its signature |
| 1256 // from its type arguments. |
| 1257 // Example: typedef T F<T>(T x) has uninstantiated signature (T x) => T. |
| 1258 // The instantiated signature of F(int) becomes (int x) => int. |
| 1259 // Note that after this step, the signature of the function type is not |
| 1260 // identical to the canonical signature of the typedef class anymore. |
| 1261 if (scope_class.IsGeneric() && !signature.HasInstantiatedSignature()) { |
| 1262 const TypeArguments& type_args = |
| 1263 TypeArguments::Handle(zone, fun_type.arguments()); |
| 1264 if (FLAG_trace_type_finalization) { |
| 1265 THR_Print("Instantiating signature '%s' of typedef '%s'\n", |
| 1266 String::Handle(zone, signature.Signature()).ToCString(), |
| 1267 String::Handle(zone, fun_type.Name()).ToCString()); |
| 1268 } |
| 1269 signature = signature.InstantiateSignatureFrom(type_args, Heap::kOld); |
| 1270 // Note that if type_args contains type parameters, signature is still |
| 1271 // uninstantiated here (typedef type parameters were substituted in the |
| 1272 // signature with typedef type arguments). |
| 1273 } |
| 1274 fun_type.set_signature(signature); |
| 1275 // The type was already marked as finalized and uninstantiated in |
| 1276 // ExpandAndFinalizeTypeArguments above when its signature was not |
| 1277 // instantiated yet. Check again by calling ResetIsFinalized(). |
| 1278 fun_type.ResetIsFinalized(); |
1252 } else { | 1279 } else { |
| 1280 const Function& signature = Function::Handle(zone, fun_type.signature()); |
1253 FinalizeSignature(cls, signature); | 1281 FinalizeSignature(cls, signature); |
1254 } | 1282 } |
1255 } | 1283 } |
1256 | 1284 |
1257 if (FLAG_trace_type_finalization) { | 1285 if (FLAG_trace_type_finalization) { |
1258 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1286 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
1259 String::Handle(zone, type.Name()).ToCString(), | 1287 String::Handle(zone, type.Name()).ToCString(), |
1260 num_expanded_type_arguments, type.ToCString()); | 1288 num_expanded_type_arguments, type.ToCString()); |
1261 } | 1289 } |
1262 | 1290 |
(...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3725 ProgramVisitor::VisitFunctions(&function_visitor); | 3753 ProgramVisitor::VisitFunctions(&function_visitor); |
3726 | 3754 |
3727 class ClearCodeClassVisitor : public ClassVisitor { | 3755 class ClearCodeClassVisitor : public ClassVisitor { |
3728 void Visit(const Class& cls) { cls.DisableAllocationStub(); } | 3756 void Visit(const Class& cls) { cls.DisableAllocationStub(); } |
3729 }; | 3757 }; |
3730 ClearCodeClassVisitor class_visitor; | 3758 ClearCodeClassVisitor class_visitor; |
3731 ProgramVisitor::VisitClasses(&class_visitor); | 3759 ProgramVisitor::VisitClasses(&class_visitor); |
3732 } | 3760 } |
3733 | 3761 |
3734 } // namespace dart | 3762 } // namespace dart |
OLD | NEW |