| 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 |