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/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
11 #include "vm/longjump.h" | 11 #include "vm/longjump.h" |
| 12 #include "vm/log.h" |
12 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
13 #include "vm/report.h" | 14 #include "vm/report.h" |
14 #include "vm/symbols.h" | 15 #include "vm/symbols.h" |
15 | 16 |
16 namespace dart { | 17 namespace dart { |
17 | 18 |
18 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 19 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
19 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 20 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
20 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 21 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
21 DECLARE_FLAG(bool, supermixin); | 22 DECLARE_FLAG(bool, supermixin); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 ASSERT(target.IsNull()); | 329 ASSERT(target.IsNull()); |
329 return; | 330 return; |
330 } | 331 } |
331 if (!target.IsNull()) { | 332 if (!target.IsNull()) { |
332 // Already resolved. | 333 // Already resolved. |
333 return; | 334 return; |
334 } | 335 } |
335 | 336 |
336 // Target is not resolved yet. | 337 // Target is not resolved yet. |
337 if (FLAG_trace_class_finalization) { | 338 if (FLAG_trace_class_finalization) { |
338 OS::Print("Resolving redirecting factory: %s\n", | 339 ISL_Print("Resolving redirecting factory: %s\n", |
339 String::Handle(factory.name()).ToCString()); | 340 String::Handle(factory.name()).ToCString()); |
340 } | 341 } |
341 type ^= FinalizeType(cls, type, kCanonicalize); | 342 type ^= FinalizeType(cls, type, kCanonicalize); |
342 factory.SetRedirectionType(type); | 343 factory.SetRedirectionType(type); |
343 if (type.IsMalformedOrMalbounded()) { | 344 if (type.IsMalformedOrMalbounded()) { |
344 ASSERT(factory.RedirectionTarget() == Function::null()); | 345 ASSERT(factory.RedirectionTarget() == Function::null()); |
345 return; | 346 return; |
346 } | 347 } |
347 ASSERT(!type.IsTypeParameter()); // Resolved in parser. | 348 ASSERT(!type.IsTypeParameter()); // Resolved in parser. |
348 if (type.IsDynamicType()) { | 349 if (type.IsDynamicType()) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 factory.SetRedirectionTarget(target_target); | 451 factory.SetRedirectionTarget(target_target); |
451 } | 452 } |
452 | 453 |
453 | 454 |
454 void ClassFinalizer::ResolveTypeClass(const Class& cls, | 455 void ClassFinalizer::ResolveTypeClass(const Class& cls, |
455 const AbstractType& type) { | 456 const AbstractType& type) { |
456 if (type.IsFinalized() || type.HasResolvedTypeClass()) { | 457 if (type.IsFinalized() || type.HasResolvedTypeClass()) { |
457 return; | 458 return; |
458 } | 459 } |
459 if (FLAG_trace_type_finalization) { | 460 if (FLAG_trace_type_finalization) { |
460 OS::Print("Resolve type class of '%s'\n", | 461 ISL_Print("Resolve type class of '%s'\n", |
461 String::Handle(type.Name()).ToCString()); | 462 String::Handle(type.Name()).ToCString()); |
462 } | 463 } |
463 | 464 |
464 // Type parameters are always resolved in the parser in the correct | 465 // Type parameters are always resolved in the parser in the correct |
465 // non-static scope or factory scope. That resolution scope is unknown here. | 466 // non-static scope or factory scope. That resolution scope is unknown here. |
466 // Being able to resolve a type parameter from class cls here would indicate | 467 // Being able to resolve a type parameter from class cls here would indicate |
467 // that the type parameter appeared in a static scope. Leaving the type as | 468 // that the type parameter appeared in a static scope. Leaving the type as |
468 // unresolved is the correct thing to do. | 469 // unresolved is the correct thing to do. |
469 | 470 |
470 // Lookup the type class. | 471 // Lookup the type class. |
(...skipping 18 matching lines...) Expand all Loading... |
489 parameterized_type.set_type_class(type_class); | 490 parameterized_type.set_type_class(type_class); |
490 } | 491 } |
491 | 492 |
492 | 493 |
493 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { | 494 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { |
494 if (type.IsResolved()) { | 495 if (type.IsResolved()) { |
495 return; | 496 return; |
496 } | 497 } |
497 ASSERT(type.IsType()); | 498 ASSERT(type.IsType()); |
498 if (FLAG_trace_type_finalization) { | 499 if (FLAG_trace_type_finalization) { |
499 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 500 ISL_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
500 } | 501 } |
501 ResolveTypeClass(cls, type); | 502 ResolveTypeClass(cls, type); |
502 if (type.IsMalformed()) { | 503 if (type.IsMalformed()) { |
503 ASSERT(type.IsResolved()); | 504 ASSERT(type.IsResolved()); |
504 return; | 505 return; |
505 } | 506 } |
506 // Mark type as resolved before resolving its type arguments in order to avoid | 507 // Mark type as resolved before resolving its type arguments in order to avoid |
507 // repeating resolution of recursive types. | 508 // repeating resolution of recursive types. |
508 Type::Cast(type).set_is_resolved(); | 509 Type::Cast(type).set_is_resolved(); |
509 // Resolve type arguments, if any. | 510 // Resolve type arguments, if any. |
510 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); | 511 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
511 if (!arguments.IsNull()) { | 512 if (!arguments.IsNull()) { |
512 const intptr_t num_arguments = arguments.Length(); | 513 const intptr_t num_arguments = arguments.Length(); |
513 AbstractType& type_argument = AbstractType::Handle(); | 514 AbstractType& type_argument = AbstractType::Handle(); |
514 for (intptr_t i = 0; i < num_arguments; i++) { | 515 for (intptr_t i = 0; i < num_arguments; i++) { |
515 type_argument = arguments.TypeAt(i); | 516 type_argument = arguments.TypeAt(i); |
516 ResolveType(cls, type_argument); | 517 ResolveType(cls, type_argument); |
517 } | 518 } |
518 } | 519 } |
519 } | 520 } |
520 | 521 |
521 | 522 |
522 void ClassFinalizer::FinalizeTypeParameters( | 523 void ClassFinalizer::FinalizeTypeParameters( |
523 const Class& cls, | 524 const Class& cls, |
524 GrowableObjectArray* pending_types) { | 525 GrowableObjectArray* pending_types) { |
525 if (FLAG_trace_type_finalization) { | 526 if (FLAG_trace_type_finalization) { |
526 OS::Print("Finalizing type parameters of '%s'\n", | 527 ISL_Print("Finalizing type parameters of '%s'\n", |
527 String::Handle(cls.Name()).ToCString()); | 528 String::Handle(cls.Name()).ToCString()); |
528 } | 529 } |
529 if (cls.IsMixinApplication()) { | 530 if (cls.IsMixinApplication()) { |
530 // Setup the type parameters of the mixin application and finalize the | 531 // Setup the type parameters of the mixin application and finalize the |
531 // mixin type. | 532 // mixin type. |
532 ApplyMixinType(cls, pending_types); | 533 ApplyMixinType(cls, pending_types); |
533 } | 534 } |
534 // The type parameter bounds are not finalized here. | 535 // The type parameter bounds are not finalized here. |
535 const TypeArguments& type_parameters = | 536 const TypeArguments& type_parameters = |
536 TypeArguments::Handle(cls.type_parameters()); | 537 TypeArguments::Handle(cls.type_parameters()); |
(...skipping 18 matching lines...) Expand all Loading... |
555 // The Dart Language Specification does not disallow the declaration and use of | 556 // The Dart Language Specification does not disallow the declaration and use of |
556 // non-contractive types (this may change). They are nevertheless disallowed | 557 // non-contractive types (this may change). They are nevertheless disallowed |
557 // as an implementation restriction in the VM since they cause divergence. | 558 // as an implementation restriction in the VM since they cause divergence. |
558 // A non-contractive type can be detected by looking at the queue of types | 559 // A non-contractive type can be detected by looking at the queue of types |
559 // pending finalization that are mutually recursive with the checked type. | 560 // pending finalization that are mutually recursive with the checked type. |
560 void ClassFinalizer::CheckRecursiveType(const Class& cls, | 561 void ClassFinalizer::CheckRecursiveType(const Class& cls, |
561 const Type& type, | 562 const Type& type, |
562 GrowableObjectArray* pending_types) { | 563 GrowableObjectArray* pending_types) { |
563 Isolate* isolate = Isolate::Current(); | 564 Isolate* isolate = Isolate::Current(); |
564 if (FLAG_trace_type_finalization) { | 565 if (FLAG_trace_type_finalization) { |
565 OS::Print("Checking recursive type '%s': %s\n", | 566 ISL_Print("Checking recursive type '%s': %s\n", |
566 String::Handle(type.Name()).ToCString(), | 567 String::Handle(type.Name()).ToCString(), |
567 type.ToCString()); | 568 type.ToCString()); |
568 } | 569 } |
569 const Class& type_cls = Class::Handle(isolate, type.type_class()); | 570 const Class& type_cls = Class::Handle(isolate, type.type_class()); |
570 const TypeArguments& arguments = | 571 const TypeArguments& arguments = |
571 TypeArguments::Handle(isolate, type.arguments()); | 572 TypeArguments::Handle(isolate, type.arguments()); |
572 // A type can only be recursive via its type arguments. | 573 // A type can only be recursive via its type arguments. |
573 ASSERT(!arguments.IsNull()); | 574 ASSERT(!arguments.IsNull()); |
574 const intptr_t num_type_args = arguments.Length(); | 575 const intptr_t num_type_args = arguments.Length(); |
575 ASSERT(num_type_args > 0); | 576 ASSERT(num_type_args > 0); |
(...skipping 10 matching lines...) Expand all Loading... |
586 } | 587 } |
587 // The type parameters are not instantiated. Verify that there is no other | 588 // The type parameters are not instantiated. Verify that there is no other |
588 // type pending finalization with the same type class, but different | 589 // type pending finalization with the same type class, but different |
589 // uninstantiated type parameters. | 590 // uninstantiated type parameters. |
590 Type& pending_type = Type::Handle(isolate); | 591 Type& pending_type = Type::Handle(isolate); |
591 TypeArguments& pending_arguments = TypeArguments::Handle(isolate); | 592 TypeArguments& pending_arguments = TypeArguments::Handle(isolate); |
592 const intptr_t num_pending_types = pending_types->Length(); | 593 const intptr_t num_pending_types = pending_types->Length(); |
593 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { | 594 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { |
594 pending_type ^= pending_types->At(i); | 595 pending_type ^= pending_types->At(i); |
595 if (FLAG_trace_type_finalization) { | 596 if (FLAG_trace_type_finalization) { |
596 OS::Print(" Comparing with pending type '%s': %s\n", | 597 ISL_Print(" Comparing with pending type '%s': %s\n", |
597 String::Handle(pending_type.Name()).ToCString(), | 598 String::Handle(pending_type.Name()).ToCString(), |
598 pending_type.ToCString()); | 599 pending_type.ToCString()); |
599 } | 600 } |
600 if ((pending_type.raw() != type.raw()) && | 601 if ((pending_type.raw() != type.raw()) && |
601 (pending_type.type_class() == type_cls.raw())) { | 602 (pending_type.type_class() == type_cls.raw())) { |
602 pending_arguments = pending_type.arguments(); | 603 pending_arguments = pending_type.arguments(); |
603 if (!pending_arguments.IsSubvectorEquivalent(arguments, | 604 if (!pending_arguments.IsSubvectorEquivalent(arguments, |
604 first_type_param, | 605 first_type_param, |
605 num_type_params) && | 606 num_type_params) && |
606 !pending_arguments.IsSubvectorInstantiated(first_type_param, | 607 !pending_arguments.IsSubvectorInstantiated(first_type_param, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 679 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
679 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 680 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
680 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 681 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
681 if (!super_type_args.IsNull()) { | 682 if (!super_type_args.IsNull()) { |
682 super_type_arg = super_type_args.TypeAt(i); | 683 super_type_arg = super_type_args.TypeAt(i); |
683 if (!super_type_arg.IsTypeRef()) { | 684 if (!super_type_arg.IsTypeRef()) { |
684 if (super_type_arg.IsBeingFinalized()) { | 685 if (super_type_arg.IsBeingFinalized()) { |
685 ASSERT(super_type_arg.IsType()); | 686 ASSERT(super_type_arg.IsType()); |
686 CheckRecursiveType(cls, Type::Cast(super_type_arg), pending_types); | 687 CheckRecursiveType(cls, Type::Cast(super_type_arg), pending_types); |
687 if (FLAG_trace_type_finalization) { | 688 if (FLAG_trace_type_finalization) { |
688 OS::Print("Creating TypeRef '%s': '%s'\n", | 689 ISL_Print("Creating TypeRef '%s': '%s'\n", |
689 String::Handle(super_type_arg.Name()).ToCString(), | 690 String::Handle(super_type_arg.Name()).ToCString(), |
690 super_type_arg.ToCString()); | 691 super_type_arg.ToCString()); |
691 } | 692 } |
692 super_type_arg = TypeRef::New(super_type_arg); | 693 super_type_arg = TypeRef::New(super_type_arg); |
693 super_type_args.SetTypeAt(i, super_type_arg); | 694 super_type_args.SetTypeAt(i, super_type_arg); |
694 } else { | 695 } else { |
695 if (!super_type_arg.IsFinalized()) { | 696 if (!super_type_arg.IsFinalized()) { |
696 super_type_arg ^= FinalizeType( | 697 super_type_arg ^= FinalizeType( |
697 cls, super_type_arg, kFinalize, pending_types); | 698 cls, super_type_arg, kFinalize, pending_types); |
698 super_type_args.SetTypeAt(i, super_type_arg); | 699 super_type_args.SetTypeAt(i, super_type_arg); |
699 // Note that super_type_arg may still not be finalized here, in | 700 // Note that super_type_arg may still not be finalized here, in |
700 // which case it is a TypeRef to a legal recursive type. | 701 // which case it is a TypeRef to a legal recursive type. |
701 } | 702 } |
702 } | 703 } |
703 } | 704 } |
704 // Instantiate super_type_arg with the current argument vector. | 705 // Instantiate super_type_arg with the current argument vector. |
705 if (!super_type_arg.IsInstantiated()) { | 706 if (!super_type_arg.IsInstantiated()) { |
706 if (FLAG_trace_type_finalization && super_type_arg.IsTypeRef()) { | 707 if (FLAG_trace_type_finalization && super_type_arg.IsTypeRef()) { |
707 AbstractType& ref_type = AbstractType::Handle( | 708 AbstractType& ref_type = AbstractType::Handle( |
708 TypeRef::Cast(super_type_arg).type()); | 709 TypeRef::Cast(super_type_arg).type()); |
709 OS::Print("Instantiating TypeRef '%s': '%s'\n" | 710 ISL_Print("Instantiating TypeRef '%s': '%s'\n" |
710 " instantiator: '%s'\n", | 711 " instantiator: '%s'\n", |
711 String::Handle(super_type_arg.Name()).ToCString(), | 712 String::Handle(super_type_arg.Name()).ToCString(), |
712 ref_type.ToCString(), | 713 ref_type.ToCString(), |
713 arguments.ToCString()); | 714 arguments.ToCString()); |
714 } | 715 } |
715 Error& error = Error::Handle(); | 716 Error& error = Error::Handle(); |
716 super_type_arg = | 717 super_type_arg = |
717 super_type_arg.InstantiateFrom(arguments, &error, trail); | 718 super_type_arg.InstantiateFrom(arguments, &error, trail); |
718 if (!error.IsNull()) { | 719 if (!error.IsNull()) { |
719 // InstantiateFrom does not report an error if the type is still | 720 // InstantiateFrom does not report an error if the type is still |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 // The bound error will be ignored in production mode. | 886 // The bound error will be ignored in production mode. |
886 if (!bound_error.IsNull()) { | 887 if (!bound_error.IsNull()) { |
887 // No compile-time error during finalization. | 888 // No compile-time error during finalization. |
888 const String& type_name = String::Handle(type.UserVisibleName()); | 889 const String& type_name = String::Handle(type.UserVisibleName()); |
889 FinalizeMalboundedType(bound_error, | 890 FinalizeMalboundedType(bound_error, |
890 Script::Handle(cls.script()), | 891 Script::Handle(cls.script()), |
891 type, | 892 type, |
892 "type '%s' has an out of bound type argument", | 893 "type '%s' has an out of bound type argument", |
893 type_name.ToCString()); | 894 type_name.ToCString()); |
894 if (FLAG_trace_type_finalization) { | 895 if (FLAG_trace_type_finalization) { |
895 OS::Print("Marking type '%s' as malbounded: %s\n", | 896 ISL_Print("Marking type '%s' as malbounded: %s\n", |
896 String::Handle(type.Name()).ToCString(), | 897 String::Handle(type.Name()).ToCString(), |
897 bound_error.ToCString()); | 898 bound_error.ToCString()); |
898 } | 899 } |
899 } | 900 } |
900 } | 901 } |
901 | 902 |
902 | 903 |
903 RawAbstractType* ClassFinalizer::FinalizeType( | 904 RawAbstractType* ClassFinalizer::FinalizeType( |
904 const Class& cls, | 905 const Class& cls, |
905 const AbstractType& type, | 906 const AbstractType& type, |
(...skipping 24 matching lines...) Expand all Loading... |
930 | 931 |
931 // A malformed type gets mapped to a finalized type. | 932 // A malformed type gets mapped to a finalized type. |
932 ResolveType(cls, type); | 933 ResolveType(cls, type); |
933 if (type.IsMalformed()) { | 934 if (type.IsMalformed()) { |
934 ASSERT(type.IsFinalized()); | 935 ASSERT(type.IsFinalized()); |
935 return type.raw(); | 936 return type.raw(); |
936 } | 937 } |
937 | 938 |
938 Isolate* isolate = Isolate::Current(); | 939 Isolate* isolate = Isolate::Current(); |
939 if (FLAG_trace_type_finalization) { | 940 if (FLAG_trace_type_finalization) { |
940 OS::Print("Finalizing type '%s' for class '%s'\n", | 941 ISL_Print("Finalizing type '%s' for class '%s'\n", |
941 String::Handle(isolate, type.Name()).ToCString(), | 942 String::Handle(isolate, type.Name()).ToCString(), |
942 cls.ToCString()); | 943 cls.ToCString()); |
943 } | 944 } |
944 | 945 |
945 if (type.IsTypeParameter()) { | 946 if (type.IsTypeParameter()) { |
946 const TypeParameter& type_parameter = TypeParameter::Cast(type); | 947 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
947 const Class& parameterized_class = | 948 const Class& parameterized_class = |
948 Class::Handle(isolate, type_parameter.parameterized_class()); | 949 Class::Handle(isolate, type_parameter.parameterized_class()); |
949 ASSERT(!parameterized_class.IsNull()); | 950 ASSERT(!parameterized_class.IsNull()); |
950 // The index must reflect the position of this type parameter in the type | 951 // The index must reflect the position of this type parameter in the type |
951 // arguments vector of its parameterized class. The offset to add is the | 952 // arguments vector of its parameterized class. The offset to add is the |
952 // number of type arguments in the super type, which is equal to the | 953 // number of type arguments in the super type, which is equal to the |
953 // difference in number of type arguments and type parameters of the | 954 // difference in number of type arguments and type parameters of the |
954 // parameterized class. | 955 // parameterized class. |
955 const intptr_t offset = parameterized_class.NumTypeArguments() - | 956 const intptr_t offset = parameterized_class.NumTypeArguments() - |
956 parameterized_class.NumTypeParameters(); | 957 parameterized_class.NumTypeParameters(); |
957 // Calling NumTypeParameters() may finalize this type parameter if it | 958 // Calling NumTypeParameters() may finalize this type parameter if it |
958 // belongs to a mixin application class. | 959 // belongs to a mixin application class. |
959 if (!type_parameter.IsFinalized()) { | 960 if (!type_parameter.IsFinalized()) { |
960 type_parameter.set_index(type_parameter.index() + offset); | 961 type_parameter.set_index(type_parameter.index() + offset); |
961 type_parameter.set_is_finalized(); | 962 type_parameter.set_is_finalized(); |
962 } else { | 963 } else { |
963 ASSERT(cls.IsMixinApplication()); | 964 ASSERT(cls.IsMixinApplication()); |
964 } | 965 } |
965 | 966 |
966 if (FLAG_trace_type_finalization) { | 967 if (FLAG_trace_type_finalization) { |
967 OS::Print("Done finalizing type parameter '%s' with index %" Pd "\n", | 968 ISL_Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
968 String::Handle(isolate, type_parameter.name()).ToCString(), | 969 String::Handle(isolate, type_parameter.name()).ToCString(), |
969 type_parameter.index()); | 970 type_parameter.index()); |
970 } | 971 } |
971 | 972 |
972 // We do not canonicalize type parameters. | 973 // We do not canonicalize type parameters. |
973 return type_parameter.raw(); | 974 return type_parameter.raw(); |
974 } | 975 } |
975 | 976 |
976 // At this point, we can only have a parameterized_type. | 977 // At this point, we can only have a parameterized_type. |
977 const Type& parameterized_type = Type::Cast(type); | 978 const Type& parameterized_type = Type::Cast(type); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 } | 1118 } |
1118 | 1119 |
1119 // If we are done finalizing a graph of mutually recursive types, check their | 1120 // If we are done finalizing a graph of mutually recursive types, check their |
1120 // bounds. | 1121 // bounds. |
1121 if (is_root_type) { | 1122 if (is_root_type) { |
1122 Type& type = Type::Handle(isolate); | 1123 Type& type = Type::Handle(isolate); |
1123 for (intptr_t i = types.Length() - 1; i >= 0; i--) { | 1124 for (intptr_t i = types.Length() - 1; i >= 0; i--) { |
1124 type ^= types.At(i); | 1125 type ^= types.At(i); |
1125 CheckTypeBounds(cls, type); | 1126 CheckTypeBounds(cls, type); |
1126 if (FLAG_trace_type_finalization && type.IsRecursive()) { | 1127 if (FLAG_trace_type_finalization && type.IsRecursive()) { |
1127 OS::Print("Done finalizing recursive type '%s': %s\n", | 1128 ISL_Print("Done finalizing recursive type '%s': %s\n", |
1128 String::Handle(isolate, type.Name()).ToCString(), | 1129 String::Handle(isolate, type.Name()).ToCString(), |
1129 type.ToCString()); | 1130 type.ToCString()); |
1130 } | 1131 } |
1131 } | 1132 } |
1132 } | 1133 } |
1133 | 1134 |
1134 // If the type class is a signature class, we are currently finalizing a | 1135 // If the type class is a signature class, we are currently finalizing a |
1135 // signature type, i.e. finalizing the result type and parameter types of the | 1136 // signature type, i.e. finalizing the result type and parameter types of the |
1136 // signature function of this signature type. | 1137 // signature function of this signature type. |
1137 // We do this after marking this type as finalized in order to allow a | 1138 // We do this after marking this type as finalized in order to allow a |
1138 // function type to refer to itself via its parameter types and result type. | 1139 // function type to refer to itself via its parameter types and result type. |
1139 if (type_class.IsSignatureClass()) { | 1140 if (type_class.IsSignatureClass()) { |
1140 // The class may be created while parsing a function body, after all | 1141 // The class may be created while parsing a function body, after all |
1141 // pending classes have already been finalized. | 1142 // pending classes have already been finalized. |
1142 FinalizeTypesInClass(type_class); | 1143 FinalizeTypesInClass(type_class); |
1143 } | 1144 } |
1144 | 1145 |
1145 if (FLAG_trace_type_finalization) { | 1146 if (FLAG_trace_type_finalization) { |
1146 OS::Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1147 ISL_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
1147 String::Handle(isolate, parameterized_type.Name()).ToCString(), | 1148 String::Handle(isolate, parameterized_type.Name()).ToCString(), |
1148 parameterized_type.arguments() == TypeArguments::null() ? | 1149 parameterized_type.arguments() == TypeArguments::null() ? |
1149 0 : num_type_arguments, | 1150 0 : num_type_arguments, |
1150 parameterized_type.ToCString()); | 1151 parameterized_type.ToCString()); |
1151 } | 1152 } |
1152 | 1153 |
1153 if (finalization >= kCanonicalize) { | 1154 if (finalization >= kCanonicalize) { |
1154 if (FLAG_trace_type_finalization && parameterized_type.IsRecursive()) { | 1155 if (FLAG_trace_type_finalization && parameterized_type.IsRecursive()) { |
1155 AbstractType& type = Type::Handle(isolate); | 1156 AbstractType& type = Type::Handle(isolate); |
1156 type = parameterized_type.Canonicalize(); | 1157 type = parameterized_type.Canonicalize(); |
1157 OS::Print("Done canonicalizing recursive type '%s': %s\n", | 1158 ISL_Print("Done canonicalizing recursive type '%s': %s\n", |
1158 String::Handle(isolate, type.Name()).ToCString(), | 1159 String::Handle(isolate, type.Name()).ToCString(), |
1159 type.ToCString()); | 1160 type.ToCString()); |
1160 return type.raw(); | 1161 return type.raw(); |
1161 } | 1162 } |
1162 return parameterized_type.Canonicalize(); | 1163 return parameterized_type.Canonicalize(); |
1163 } else { | 1164 } else { |
1164 return parameterized_type.raw(); | 1165 return parameterized_type.raw(); |
1165 } | 1166 } |
1166 } | 1167 } |
1167 | 1168 |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 library.LookupLocalClass(inserted_class_name)); | 1850 library.LookupLocalClass(inserted_class_name)); |
1850 if (inserted_class.IsNull()) { | 1851 if (inserted_class.IsNull()) { |
1851 inserted_class_name = Symbols::New(inserted_class_name); | 1852 inserted_class_name = Symbols::New(inserted_class_name); |
1852 const Script& script = Script::Handle(isolate, mixin_app_class.script()); | 1853 const Script& script = Script::Handle(isolate, mixin_app_class.script()); |
1853 inserted_class = Class::New( | 1854 inserted_class = Class::New( |
1854 inserted_class_name, script, mixin_app_class.token_pos()); | 1855 inserted_class_name, script, mixin_app_class.token_pos()); |
1855 inserted_class.set_is_synthesized_class(); | 1856 inserted_class.set_is_synthesized_class(); |
1856 library.AddClass(inserted_class); | 1857 library.AddClass(inserted_class); |
1857 | 1858 |
1858 if (FLAG_trace_class_finalization) { | 1859 if (FLAG_trace_class_finalization) { |
1859 OS::Print("Creating mixin application alias %s\n", | 1860 ISL_Print("Creating mixin application alias %s\n", |
1860 inserted_class.ToCString()); | 1861 inserted_class.ToCString()); |
1861 } | 1862 } |
1862 | 1863 |
1863 // The super type of the inserted class is identical to the super type of | 1864 // The super type of the inserted class is identical to the super type of |
1864 // this mixin application class, except that it must refer to the type | 1865 // this mixin application class, except that it must refer to the type |
1865 // parameters of the inserted class rather than to those of the mixin | 1866 // parameters of the inserted class rather than to those of the mixin |
1866 // application class. | 1867 // application class. |
1867 // The type arguments of the super type will be set properly when calling | 1868 // The type arguments of the super type will be set properly when calling |
1868 // CloneMixinAppTypeParameters on the inserted class, as long as the super | 1869 // CloneMixinAppTypeParameters on the inserted class, as long as the super |
1869 // type class is set properly. | 1870 // type class is set properly. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 super_type = Type::New(inserted_class, | 1985 super_type = Type::New(inserted_class, |
1985 new_super_type_args, | 1986 new_super_type_args, |
1986 mixin_app_class.token_pos()); | 1987 mixin_app_class.token_pos()); |
1987 mixin_app_class.set_super_type(super_type); | 1988 mixin_app_class.set_super_type(super_type); |
1988 | 1989 |
1989 // Mark this mixin application class as being an alias. | 1990 // Mark this mixin application class as being an alias. |
1990 mixin_app_class.set_is_mixin_app_alias(); | 1991 mixin_app_class.set_is_mixin_app_alias(); |
1991 ASSERT(!mixin_app_class.is_type_finalized()); | 1992 ASSERT(!mixin_app_class.is_type_finalized()); |
1992 ASSERT(!mixin_app_class.is_mixin_type_applied()); | 1993 ASSERT(!mixin_app_class.is_mixin_type_applied()); |
1993 if (FLAG_trace_class_finalization) { | 1994 if (FLAG_trace_class_finalization) { |
1994 OS::Print("Inserting class '%s' %s\n" | 1995 ISL_Print("Inserting class '%s' %s\n" |
1995 " as super type '%s' with %" Pd " type args: %s\n" | 1996 " as super type '%s' with %" Pd " type args: %s\n" |
1996 " of mixin application alias '%s' %s\n", | 1997 " of mixin application alias '%s' %s\n", |
1997 String::Handle(inserted_class.Name()).ToCString(), | 1998 String::Handle(inserted_class.Name()).ToCString(), |
1998 TypeArguments::Handle( | 1999 TypeArguments::Handle( |
1999 inserted_class.type_parameters()).ToCString(), | 2000 inserted_class.type_parameters()).ToCString(), |
2000 String::Handle(isolate, super_type.Name()).ToCString(), | 2001 String::Handle(isolate, super_type.Name()).ToCString(), |
2001 num_super_type_params + num_aliased_mixin_type_params, | 2002 num_super_type_params + num_aliased_mixin_type_params, |
2002 super_type.ToCString(), | 2003 super_type.ToCString(), |
2003 String::Handle(mixin_app_class.Name()).ToCString(), | 2004 String::Handle(mixin_app_class.Name()).ToCString(), |
2004 TypeArguments::Handle( | 2005 TypeArguments::Handle( |
2005 mixin_app_class.type_parameters()).ToCString()); | 2006 mixin_app_class.type_parameters()).ToCString()); |
2006 } | 2007 } |
2007 } | 2008 } |
2008 | 2009 |
2009 | 2010 |
2010 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, | 2011 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, |
2011 GrowableObjectArray* pending_types) { | 2012 GrowableObjectArray* pending_types) { |
2012 if (mixin_app_class.is_mixin_type_applied()) { | 2013 if (mixin_app_class.is_mixin_type_applied()) { |
2013 return; | 2014 return; |
2014 } | 2015 } |
2015 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 2016 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
2016 ASSERT(!mixin_type.IsNull()); | 2017 ASSERT(!mixin_type.IsNull()); |
2017 ASSERT(mixin_type.HasResolvedTypeClass()); | 2018 ASSERT(mixin_type.HasResolvedTypeClass()); |
2018 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 2019 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
2019 | 2020 |
2020 if (FLAG_trace_class_finalization) { | 2021 if (FLAG_trace_class_finalization) { |
2021 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n", | 2022 ISL_Print("Applying mixin type '%s' to %s at pos %" Pd "\n", |
2022 String::Handle(mixin_type.Name()).ToCString(), | 2023 String::Handle(mixin_type.Name()).ToCString(), |
2023 mixin_app_class.ToCString(), | 2024 mixin_app_class.ToCString(), |
2024 mixin_app_class.token_pos()); | 2025 mixin_app_class.token_pos()); |
2025 } | 2026 } |
2026 | 2027 |
2027 // Check for illegal self references. | 2028 // Check for illegal self references. |
2028 GrowableArray<intptr_t> visited_mixins; | 2029 GrowableArray<intptr_t> visited_mixins; |
2029 if (!IsMixinCycleFree(mixin_class, &visited_mixins)) { | 2030 if (!IsMixinCycleFree(mixin_class, &visited_mixins)) { |
2030 const String& class_name = String::Handle(mixin_class.Name()); | 2031 const String& class_name = String::Handle(mixin_class.Name()); |
2031 ReportError(mixin_class, mixin_class.token_pos(), | 2032 ReportError(mixin_class, mixin_class.token_pos(), |
(...skipping 22 matching lines...) Expand all Loading... |
2054 | 2055 |
2055 // Copy type parameters to mixin application class. | 2056 // Copy type parameters to mixin application class. |
2056 CloneMixinAppTypeParameters(mixin_app_class); | 2057 CloneMixinAppTypeParameters(mixin_app_class); |
2057 | 2058 |
2058 // Verify that no restricted class is used as a mixin by checking the | 2059 // Verify that no restricted class is used as a mixin by checking the |
2059 // interfaces of the mixin application class, which implements its mixin. | 2060 // interfaces of the mixin application class, which implements its mixin. |
2060 GrowableArray<intptr_t> visited_interfaces; | 2061 GrowableArray<intptr_t> visited_interfaces; |
2061 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); | 2062 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); |
2062 | 2063 |
2063 if (FLAG_trace_class_finalization) { | 2064 if (FLAG_trace_class_finalization) { |
2064 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n", | 2065 ISL_Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n", |
2065 String::Handle(mixin_type.Name()).ToCString(), | 2066 String::Handle(mixin_type.Name()).ToCString(), |
2066 String::Handle(mixin_app_class.Name()).ToCString(), | 2067 String::Handle(mixin_app_class.Name()).ToCString(), |
2067 TypeArguments::Handle( | 2068 TypeArguments::Handle( |
2068 mixin_app_class.type_parameters()).ToCString(), | 2069 mixin_app_class.type_parameters()).ToCString(), |
2069 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); | 2070 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); |
2070 } | 2071 } |
2071 // Mark the application class as having been applied its mixin type in order | 2072 // Mark the application class as having been applied its mixin type in order |
2072 // to avoid cycles while finalizing its mixin type. | 2073 // to avoid cycles while finalizing its mixin type. |
2073 mixin_app_class.set_is_mixin_type_applied(); | 2074 mixin_app_class.set_is_mixin_type_applied(); |
2074 // Finalize the mixin type, which may have been changed in case | 2075 // Finalize the mixin type, which may have been changed in case |
(...skipping 25 matching lines...) Expand all Loading... |
2100 if (func.IsGenerativeConstructor()) { | 2101 if (func.IsGenerativeConstructor()) { |
2101 // Build constructor name from mixin application class name | 2102 // Build constructor name from mixin application class name |
2102 // and name of cloned super class constructor. | 2103 // and name of cloned super class constructor. |
2103 const String& ctor_name = String::Handle(func.name()); | 2104 const String& ctor_name = String::Handle(func.name()); |
2104 String& clone_name = String::Handle( | 2105 String& clone_name = String::Handle( |
2105 String::SubString(ctor_name, super_name.Length())); | 2106 String::SubString(ctor_name, super_name.Length())); |
2106 clone_name = String::Concat(mixin_name, clone_name); | 2107 clone_name = String::Concat(mixin_name, clone_name); |
2107 clone_name = Symbols::New(clone_name); | 2108 clone_name = Symbols::New(clone_name); |
2108 | 2109 |
2109 if (FLAG_trace_class_finalization) { | 2110 if (FLAG_trace_class_finalization) { |
2110 OS::Print("Cloning constructor '%s' as '%s'\n", | 2111 ISL_Print("Cloning constructor '%s' as '%s'\n", |
2111 ctor_name.ToCString(), | 2112 ctor_name.ToCString(), |
2112 clone_name.ToCString()); | 2113 clone_name.ToCString()); |
2113 } | 2114 } |
2114 const Function& clone = Function::Handle( | 2115 const Function& clone = Function::Handle( |
2115 Function::New(clone_name, | 2116 Function::New(clone_name, |
2116 func.kind(), | 2117 func.kind(), |
2117 func.is_static(), | 2118 func.is_static(), |
2118 false, // Not const. | 2119 false, // Not const. |
2119 false, // Not abstract. | 2120 false, // Not abstract. |
2120 false, // Not external. | 2121 false, // Not external. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2155 // If the mixin is a mixin application alias class, there are no members to | 2156 // If the mixin is a mixin application alias class, there are no members to |
2156 // apply here. A new synthesized class representing the aliased mixin | 2157 // apply here. A new synthesized class representing the aliased mixin |
2157 // application class was inserted in the super chain of this mixin application | 2158 // application class was inserted in the super chain of this mixin application |
2158 // class. Members of the actual mixin class will be applied when visiting | 2159 // class. Members of the actual mixin class will be applied when visiting |
2159 // the mixin application class referring to the actual mixin. | 2160 // the mixin application class referring to the actual mixin. |
2160 ASSERT(!mixin_cls.is_mixin_app_alias() || | 2161 ASSERT(!mixin_cls.is_mixin_app_alias() || |
2161 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); | 2162 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); |
2162 // A default constructor will be created for the mixin app alias class. | 2163 // A default constructor will be created for the mixin app alias class. |
2163 | 2164 |
2164 if (FLAG_trace_class_finalization) { | 2165 if (FLAG_trace_class_finalization) { |
2165 OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n", | 2166 ISL_Print("Applying mixin members of %s to %s at pos %" Pd "\n", |
2166 mixin_cls.ToCString(), | 2167 mixin_cls.ToCString(), |
2167 cls.ToCString(), | 2168 cls.ToCString(), |
2168 cls.token_pos()); | 2169 cls.token_pos()); |
2169 } | 2170 } |
2170 | 2171 |
2171 const GrowableObjectArray& cloned_funcs = | 2172 const GrowableObjectArray& cloned_funcs = |
2172 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | 2173 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
2173 | 2174 |
2174 CreateForwardingConstructors(cls, cloned_funcs); | 2175 CreateForwardingConstructors(cls, cloned_funcs); |
2175 | 2176 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2215 // Static fields are shared between the mixin class and the mixin | 2216 // Static fields are shared between the mixin class and the mixin |
2216 // application class. | 2217 // application class. |
2217 if (!field.is_static()) { | 2218 if (!field.is_static()) { |
2218 field = field.Clone(cls); | 2219 field = field.Clone(cls); |
2219 cloned_fields.Add(field); | 2220 cloned_fields.Add(field); |
2220 } | 2221 } |
2221 } | 2222 } |
2222 cls.AddFields(cloned_fields); | 2223 cls.AddFields(cloned_fields); |
2223 | 2224 |
2224 if (FLAG_trace_class_finalization) { | 2225 if (FLAG_trace_class_finalization) { |
2225 OS::Print("Done applying mixin members of %s to %s\n", | 2226 ISL_Print("Done applying mixin members of %s to %s\n", |
2226 mixin_cls.ToCString(), | 2227 mixin_cls.ToCString(), |
2227 cls.ToCString()); | 2228 cls.ToCString()); |
2228 } | 2229 } |
2229 } | 2230 } |
2230 | 2231 |
2231 | 2232 |
2232 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { | 2233 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
2233 HANDLESCOPE(Isolate::Current()); | 2234 HANDLESCOPE(Isolate::Current()); |
2234 if (cls.is_type_finalized()) { | 2235 if (cls.is_type_finalized()) { |
2235 return; | 2236 return; |
2236 } | 2237 } |
2237 if (FLAG_trace_class_finalization) { | 2238 if (FLAG_trace_class_finalization) { |
2238 OS::Print("Finalize types in %s\n", cls.ToCString()); | 2239 ISL_Print("Finalize types in %s\n", cls.ToCString()); |
2239 } | 2240 } |
2240 if (!IsSuperCycleFree(cls)) { | 2241 if (!IsSuperCycleFree(cls)) { |
2241 const String& name = String::Handle(cls.Name()); | 2242 const String& name = String::Handle(cls.Name()); |
2242 ReportError(cls, cls.token_pos(), | 2243 ReportError(cls, cls.token_pos(), |
2243 "class '%s' has a cycle in its superclass relationship", | 2244 "class '%s' has a cycle in its superclass relationship", |
2244 name.ToCString()); | 2245 name.ToCString()); |
2245 } | 2246 } |
2246 // Finalize super class. | 2247 // Finalize super class. |
2247 Class& super_class = Class::Handle(cls.SuperClass()); | 2248 Class& super_class = Class::Handle(cls.SuperClass()); |
2248 if (!super_class.IsNull()) { | 2249 if (!super_class.IsNull()) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2361 } | 2362 } |
2362 } | 2363 } |
2363 | 2364 |
2364 | 2365 |
2365 void ClassFinalizer::FinalizeClass(const Class& cls) { | 2366 void ClassFinalizer::FinalizeClass(const Class& cls) { |
2366 HANDLESCOPE(Isolate::Current()); | 2367 HANDLESCOPE(Isolate::Current()); |
2367 if (cls.is_finalized()) { | 2368 if (cls.is_finalized()) { |
2368 return; | 2369 return; |
2369 } | 2370 } |
2370 if (FLAG_trace_class_finalization) { | 2371 if (FLAG_trace_class_finalization) { |
2371 OS::Print("Finalize %s\n", cls.ToCString()); | 2372 ISL_Print("Finalize %s\n", cls.ToCString()); |
2372 } | 2373 } |
2373 if (cls.is_patch()) { | 2374 if (cls.is_patch()) { |
2374 // The fields and functions of a patch class are copied to the | 2375 // The fields and functions of a patch class are copied to the |
2375 // patched class after parsing. There is nothing to finalize. | 2376 // patched class after parsing. There is nothing to finalize. |
2376 ASSERT(Array::Handle(cls.functions()).Length() == 0); | 2377 ASSERT(Array::Handle(cls.functions()).Length() == 0); |
2377 ASSERT(Array::Handle(cls.fields()).Length() == 0); | 2378 ASSERT(Array::Handle(cls.fields()).Length() == 0); |
2378 cls.set_is_finalized(); | 2379 cls.set_is_finalized(); |
2379 return; | 2380 return; |
2380 } | 2381 } |
2381 if (cls.IsMixinApplication()) { | 2382 if (cls.IsMixinApplication()) { |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2734 interfaces.SetAt(0, generic_mixin_type); | 2735 interfaces.SetAt(0, generic_mixin_type); |
2735 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | 2736 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
2736 mixin_app_class.set_interfaces(interfaces); | 2737 mixin_app_class.set_interfaces(interfaces); |
2737 mixin_app_class.set_is_synthesized_class(); | 2738 mixin_app_class.set_is_synthesized_class(); |
2738 library.AddClass(mixin_app_class); | 2739 library.AddClass(mixin_app_class); |
2739 | 2740 |
2740 // No need to add the new class to pending_classes, since it will be | 2741 // No need to add the new class to pending_classes, since it will be |
2741 // processed via the super_type chain of a pending class. | 2742 // processed via the super_type chain of a pending class. |
2742 | 2743 |
2743 if (FLAG_trace_class_finalization) { | 2744 if (FLAG_trace_class_finalization) { |
2744 OS::Print("Creating mixin application %s\n", | 2745 ISL_Print("Creating mixin application %s\n", |
2745 mixin_app_class.ToCString()); | 2746 mixin_app_class.ToCString()); |
2746 } | 2747 } |
2747 } | 2748 } |
2748 // This mixin application class becomes the type class of the super type of | 2749 // This mixin application class becomes the type class of the super type of |
2749 // the next mixin application class. It is however too early to provide the | 2750 // the next mixin application class. It is however too early to provide the |
2750 // correct super type arguments. We use the raw type for now. | 2751 // correct super type arguments. We use the raw type for now. |
2751 mixin_super_type = Type::New(mixin_app_class, | 2752 mixin_super_type = Type::New(mixin_app_class, |
2752 Object::null_type_arguments(), | 2753 Object::null_type_arguments(), |
2753 mixin_type.token_pos()); | 2754 mixin_type.token_pos()); |
2754 } | 2755 } |
2755 TypeArguments& mixin_app_args = TypeArguments::Handle(isolate); | 2756 TypeArguments& mixin_app_args = TypeArguments::Handle(isolate); |
2756 if (type_args.Length() > 0) { | 2757 if (type_args.Length() > 0) { |
2757 mixin_app_args = TypeArguments::New(type_args.Length()); | 2758 mixin_app_args = TypeArguments::New(type_args.Length()); |
2758 AbstractType& type_arg = AbstractType::Handle(isolate); | 2759 AbstractType& type_arg = AbstractType::Handle(isolate); |
2759 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2760 for (intptr_t i = 0; i < type_args.Length(); i++) { |
2760 type_arg ^= type_args.At(i); | 2761 type_arg ^= type_args.At(i); |
2761 mixin_app_args.SetTypeAt(i, type_arg); | 2762 mixin_app_args.SetTypeAt(i, type_arg); |
2762 } | 2763 } |
2763 } | 2764 } |
2764 if (FLAG_trace_class_finalization) { | 2765 if (FLAG_trace_class_finalization) { |
2765 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", | 2766 ISL_Print("ResolveMixinAppType: mixin appl type args: %s\n", |
2766 mixin_app_args.ToCString()); | 2767 mixin_app_args.ToCString()); |
2767 } | 2768 } |
2768 // The mixin application class at depth k is a subclass of mixin application | 2769 // The mixin application class at depth k is a subclass of mixin application |
2769 // class at depth k - 1. Build a new super type with the class at the highest | 2770 // class at depth k - 1. Build a new super type with the class at the highest |
2770 // depth (the last one processed by the loop above) as the type class and the | 2771 // depth (the last one processed by the loop above) as the type class and the |
2771 // collected type arguments from the super type and all mixin types. | 2772 // collected type arguments from the super type and all mixin types. |
2772 // This super type replaces the MixinAppType object in the class that extends | 2773 // This super type replaces the MixinAppType object in the class that extends |
2773 // the mixin application. | 2774 // the mixin application. |
2774 return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos()); | 2775 return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos()); |
2775 } | 2776 } |
2776 | 2777 |
2777 | 2778 |
2778 // Recursively walks the graph of explicitly declared super type and | 2779 // Recursively walks the graph of explicitly declared super type and |
2779 // interfaces, resolving unresolved super types and interfaces. | 2780 // interfaces, resolving unresolved super types and interfaces. |
2780 // Reports an error if there is an interface reference that cannot be | 2781 // Reports an error if there is an interface reference that cannot be |
2781 // resolved, or if there is a cycle in the graph. We detect cycles by | 2782 // resolved, or if there is a cycle in the graph. We detect cycles by |
2782 // remembering interfaces we've visited in each path through the | 2783 // remembering interfaces we've visited in each path through the |
2783 // graph. If we visit an interface a second time on a given path, | 2784 // graph. If we visit an interface a second time on a given path, |
2784 // we found a loop. | 2785 // we found a loop. |
2785 void ClassFinalizer::ResolveSuperTypeAndInterfaces( | 2786 void ClassFinalizer::ResolveSuperTypeAndInterfaces( |
2786 const Class& cls, GrowableArray<intptr_t>* visited) { | 2787 const Class& cls, GrowableArray<intptr_t>* visited) { |
2787 if (cls.is_cycle_free()) { | 2788 if (cls.is_cycle_free()) { |
2788 return; | 2789 return; |
2789 } | 2790 } |
2790 ASSERT(visited != NULL); | 2791 ASSERT(visited != NULL); |
2791 if (FLAG_trace_class_finalization) { | 2792 if (FLAG_trace_class_finalization) { |
2792 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); | 2793 ISL_Print("Resolving super and interfaces: %s\n", cls.ToCString()); |
2793 } | 2794 } |
2794 Isolate* isolate = Isolate::Current(); | 2795 Isolate* isolate = Isolate::Current(); |
2795 const intptr_t cls_index = cls.id(); | 2796 const intptr_t cls_index = cls.id(); |
2796 for (intptr_t i = 0; i < visited->length(); i++) { | 2797 for (intptr_t i = 0; i < visited->length(); i++) { |
2797 if ((*visited)[i] == cls_index) { | 2798 if ((*visited)[i] == cls_index) { |
2798 // We have already visited class 'cls'. We found a cycle. | 2799 // We have already visited class 'cls'. We found a cycle. |
2799 const String& class_name = String::Handle(isolate, cls.Name()); | 2800 const String& class_name = String::Handle(isolate, cls.Name()); |
2800 ReportError(cls, cls.token_pos(), | 2801 ReportError(cls, cls.token_pos(), |
2801 "cyclic reference found for class '%s'", | 2802 "cyclic reference found for class '%s'", |
2802 class_name.ToCString()); | 2803 class_name.ToCString()); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2988 "const class '%s' has non-final field '%s'", | 2989 "const class '%s' has non-final field '%s'", |
2989 class_name.ToCString(), field_name.ToCString()); | 2990 class_name.ToCString(), field_name.ToCString()); |
2990 } | 2991 } |
2991 } | 2992 } |
2992 } | 2993 } |
2993 | 2994 |
2994 | 2995 |
2995 void ClassFinalizer::PrintClassInformation(const Class& cls) { | 2996 void ClassFinalizer::PrintClassInformation(const Class& cls) { |
2996 HANDLESCOPE(Isolate::Current()); | 2997 HANDLESCOPE(Isolate::Current()); |
2997 const String& class_name = String::Handle(cls.Name()); | 2998 const String& class_name = String::Handle(cls.Name()); |
2998 OS::Print("class '%s'", class_name.ToCString()); | 2999 ISL_Print("class '%s'", class_name.ToCString()); |
2999 const Library& library = Library::Handle(cls.library()); | 3000 const Library& library = Library::Handle(cls.library()); |
3000 if (!library.IsNull()) { | 3001 if (!library.IsNull()) { |
3001 OS::Print(" library '%s%s':\n", | 3002 ISL_Print(" library '%s%s':\n", |
3002 String::Handle(library.url()).ToCString(), | 3003 String::Handle(library.url()).ToCString(), |
3003 String::Handle(library.private_key()).ToCString()); | 3004 String::Handle(library.private_key()).ToCString()); |
3004 } else { | 3005 } else { |
3005 OS::Print(" (null library):\n"); | 3006 ISL_Print(" (null library):\n"); |
3006 } | 3007 } |
3007 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 3008 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
3008 if (super_type.IsNull()) { | 3009 if (super_type.IsNull()) { |
3009 OS::Print(" Super: NULL"); | 3010 ISL_Print(" Super: NULL"); |
3010 } else { | 3011 } else { |
3011 const String& super_name = String::Handle(super_type.Name()); | 3012 const String& super_name = String::Handle(super_type.Name()); |
3012 OS::Print(" Super: %s", super_name.ToCString()); | 3013 ISL_Print(" Super: %s", super_name.ToCString()); |
3013 } | 3014 } |
3014 const Array& interfaces_array = Array::Handle(cls.interfaces()); | 3015 const Array& interfaces_array = Array::Handle(cls.interfaces()); |
3015 if (interfaces_array.Length() > 0) { | 3016 if (interfaces_array.Length() > 0) { |
3016 OS::Print("; interfaces: "); | 3017 ISL_Print("; interfaces: "); |
3017 AbstractType& interface = AbstractType::Handle(); | 3018 AbstractType& interface = AbstractType::Handle(); |
3018 intptr_t len = interfaces_array.Length(); | 3019 intptr_t len = interfaces_array.Length(); |
3019 for (intptr_t i = 0; i < len; i++) { | 3020 for (intptr_t i = 0; i < len; i++) { |
3020 interface ^= interfaces_array.At(i); | 3021 interface ^= interfaces_array.At(i); |
3021 OS::Print(" %s ", interface.ToCString()); | 3022 ISL_Print(" %s ", interface.ToCString()); |
3022 } | 3023 } |
3023 } | 3024 } |
3024 OS::Print("\n"); | 3025 ISL_Print("\n"); |
3025 const Array& functions_array = Array::Handle(cls.functions()); | 3026 const Array& functions_array = Array::Handle(cls.functions()); |
3026 Function& function = Function::Handle(); | 3027 Function& function = Function::Handle(); |
3027 intptr_t len = functions_array.Length(); | 3028 intptr_t len = functions_array.Length(); |
3028 for (intptr_t i = 0; i < len; i++) { | 3029 for (intptr_t i = 0; i < len; i++) { |
3029 function ^= functions_array.At(i); | 3030 function ^= functions_array.At(i); |
3030 OS::Print(" %s\n", function.ToCString()); | 3031 ISL_Print(" %s\n", function.ToCString()); |
3031 } | 3032 } |
3032 const Array& fields_array = Array::Handle(cls.fields()); | 3033 const Array& fields_array = Array::Handle(cls.fields()); |
3033 Field& field = Field::Handle(); | 3034 Field& field = Field::Handle(); |
3034 len = fields_array.Length(); | 3035 len = fields_array.Length(); |
3035 for (intptr_t i = 0; i < len; i++) { | 3036 for (intptr_t i = 0; i < len; i++) { |
3036 field ^= fields_array.At(i); | 3037 field ^= fields_array.At(i); |
3037 OS::Print(" %s\n", field.ToCString()); | 3038 ISL_Print(" %s\n", field.ToCString()); |
3038 } | 3039 } |
3039 } | 3040 } |
3040 | 3041 |
3041 // Either report an error or mark the type as malformed. | 3042 // Either report an error or mark the type as malformed. |
3042 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, | 3043 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, |
3043 const Script& script, | 3044 const Script& script, |
3044 const Type& type, | 3045 const Type& type, |
3045 const char* format, | 3046 const char* format, |
3046 va_list args) { | 3047 va_list args) { |
3047 LanguageError& error = LanguageError::Handle( | 3048 LanguageError& error = LanguageError::Handle( |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3219 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3220 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3220 field ^= fields_array.At(0); | 3221 field ^= fields_array.At(0); |
3221 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3222 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3222 name ^= field.name(); | 3223 name ^= field.name(); |
3223 expected_name ^= String::New("_data"); | 3224 expected_name ^= String::New("_data"); |
3224 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3225 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3225 #endif | 3226 #endif |
3226 } | 3227 } |
3227 | 3228 |
3228 } // namespace dart | 3229 } // namespace dart |
OLD | NEW |