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