| 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 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 for (intptr_t i = 0; i < num_types; i++) { | 505 for (intptr_t i = 0; i < num_types; i++) { |
| 506 type_parameter ^= type_parameters.TypeAt(i); | 506 type_parameter ^= type_parameters.TypeAt(i); |
| 507 type_parameter ^= FinalizeType( | 507 type_parameter ^= FinalizeType( |
| 508 cls, type_parameter, kFinalize, pending_types); | 508 cls, type_parameter, kFinalize, pending_types); |
| 509 type_parameters.SetTypeAt(i, type_parameter); | 509 type_parameters.SetTypeAt(i, type_parameter); |
| 510 } | 510 } |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 | 513 |
| 514 | 514 |
| 515 // This function reports a compilation error if the recursive 'type' being |
| 516 // finalized is a non-contractive type, i.e. if the induced type set of the |
| 517 // instantiation of 'type' with its own type parameters is not finite (see |
| 518 // the Dart Language Specification for the definition of the induced type set). |
| 519 // This can be detected by looking at the queue of types pending finalization |
| 520 // that may be mutually recursive with the checked type. |
| 521 void ClassFinalizer::CheckRecursiveType(const Class& cls, |
| 522 const Type& type, |
| 523 GrowableObjectArray* pending_types) { |
| 524 Isolate* isolate = Isolate::Current(); |
| 525 if (FLAG_trace_type_finalization) { |
| 526 OS::Print("Checking recursive type '%s' for class '%s'\n", |
| 527 String::Handle(type.Name()).ToCString(), |
| 528 cls.ToCString()); |
| 529 } |
| 530 const Class& type_cls = Class::Handle(isolate, type.type_class()); |
| 531 const TypeArguments& arguments = |
| 532 TypeArguments::Handle(isolate, type.arguments()); |
| 533 // A type can only be recursive via its type arguments. |
| 534 ASSERT(!arguments.IsNull()); |
| 535 const intptr_t num_type_args = arguments.Length(); |
| 536 ASSERT(num_type_args > 0); |
| 537 ASSERT(num_type_args == type_cls.NumTypeArguments()); |
| 538 const intptr_t num_type_params = type_cls.NumTypeParameters(); |
| 539 const intptr_t first_type_param = num_type_args - num_type_params; |
| 540 // If the type is not generic (num_type_params == 0) or if its type parameters |
| 541 // are instantiated, no divergence can occur. Note that if the type parameters |
| 542 // are null, i.e. if the generic type is raw, they are considered |
| 543 // instantiated and no divergence can occur. |
| 544 if ((num_type_params == 0) || |
| 545 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) { |
| 546 return; |
| 547 } |
| 548 // The type parameters are not instantiated. Verify that there is no other |
| 549 // type pending finalization with the same type class, but different |
| 550 // uninstantiated type parameters. |
| 551 Type& pending_type = Type::Handle(isolate); |
| 552 TypeArguments& pending_arguments = TypeArguments::Handle(isolate); |
| 553 const intptr_t num_pending_types = pending_types->Length(); |
| 554 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { |
| 555 pending_type ^= pending_types->At(i); |
| 556 if (FLAG_trace_type_finalization) { |
| 557 OS::Print(" Comparing with pending type '%s'\n", |
| 558 String::Handle(pending_type.Name()).ToCString()); |
| 559 } |
| 560 if ((pending_type.raw() != type.raw()) && |
| 561 (pending_type.type_class() == type_cls.raw())) { |
| 562 pending_arguments = pending_type.arguments(); |
| 563 if (!pending_arguments.IsSubvectorEquivalent(arguments, |
| 564 first_type_param, |
| 565 num_type_params) && |
| 566 !pending_arguments.IsSubvectorInstantiated(first_type_param, |
| 567 num_type_params)) { |
| 568 // Reject the non-contractive recursive type. |
| 569 const Script& script = Script::Handle(isolate, cls.script()); |
| 570 const String& type_name = String::Handle(isolate, type.Name()); |
| 571 ReportError(Error::Handle(isolate), // No previous error. |
| 572 script, type.token_pos(), |
| 573 "illegal recursive type '%s'", |
| 574 type_name.ToCString()); |
| 575 } |
| 576 } |
| 577 } |
| 578 } |
| 579 |
| 580 |
| 515 // Finalize the type argument vector 'arguments' of the type defined by the | 581 // Finalize the type argument vector 'arguments' of the type defined by the |
| 516 // class 'cls' parameterized with the type arguments 'cls_args'. | 582 // class 'cls' parameterized with the type arguments 'cls_args'. |
| 517 // The vector 'cls_args' is already initialized as a subvector at the correct | 583 // The vector 'cls_args' is already initialized as a subvector at the correct |
| 518 // position in the passed in 'arguments' vector. | 584 // position in the passed in 'arguments' vector. |
| 519 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at | 585 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at |
| 520 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' | 586 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' |
| 521 // vector. | 587 // vector. |
| 522 // The type argument vector of cls may overlap the type argument vector of its | 588 // The type argument vector of cls may overlap the type argument vector of its |
| 523 // super class. In case of an overlap, the overlapped type arguments of the | 589 // super class. In case of an overlap, the overlapped type arguments of the |
| 524 // super class are already initialized. The still uninitialized ones have an | 590 // super class are already initialized. The still uninitialized ones have an |
| (...skipping 11 matching lines...) Expand all Loading... |
| 536 // class B<T> extends A<int> { ... } | 602 // class B<T> extends A<int> { ... } |
| 537 // Input: C<String, double> expressed as | 603 // Input: C<String, double> expressed as |
| 538 // cls = C, arguments = [dynamic, String, double], | 604 // cls = C, arguments = [dynamic, String, double], |
| 539 // num_uninitialized_arguments = 1, | 605 // num_uninitialized_arguments = 1, |
| 540 // i.e. cls_args = [String, double], offset = 1, length = 2. | 606 // i.e. cls_args = [String, double], offset = 1, length = 2. |
| 541 // Output: arguments = [int, String, double] | 607 // Output: arguments = [int, String, double] |
| 542 // | 608 // |
| 543 // It is too early to canonicalize the type arguments of the vector, because | 609 // It is too early to canonicalize the type arguments of the vector, because |
| 544 // several type argument vectors may be mutually recursive and finalized at the | 610 // several type argument vectors may be mutually recursive and finalized at the |
| 545 // same time. Canonicalization happens when pending types are processed. | 611 // same time. Canonicalization happens when pending types are processed. |
| 612 // The trail is required to correctly instantiate a recursive type argument |
| 613 // of the super type. |
| 546 void ClassFinalizer::FinalizeTypeArguments( | 614 void ClassFinalizer::FinalizeTypeArguments( |
| 547 const Class& cls, | 615 const Class& cls, |
| 548 const TypeArguments& arguments, | 616 const TypeArguments& arguments, |
| 549 intptr_t num_uninitialized_arguments, | 617 intptr_t num_uninitialized_arguments, |
| 550 Error* bound_error, | 618 Error* bound_error, |
| 551 GrowableObjectArray* pending_types) { | 619 GrowableObjectArray* pending_types, |
| 620 GrowableObjectArray* trail) { |
| 552 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 621 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 553 if (!cls.is_type_finalized()) { | 622 if (!cls.is_type_finalized()) { |
| 554 FinalizeTypeParameters(cls, pending_types); | 623 FinalizeTypeParameters(cls, pending_types); |
| 555 ResolveUpperBounds(cls); | 624 ResolveUpperBounds(cls); |
| 556 } | 625 } |
| 557 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 626 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 558 if (!super_type.IsNull()) { | 627 if (!super_type.IsNull()) { |
| 559 const Class& super_class = Class::Handle(super_type.type_class()); | 628 const Class& super_class = Class::Handle(super_type.type_class()); |
| 560 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 629 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 561 const intptr_t num_super_type_args = super_class.NumTypeArguments(); | 630 const intptr_t num_super_type_args = super_class.NumTypeArguments(); |
| 562 ASSERT(num_super_type_args == | 631 ASSERT(num_super_type_args == |
| 563 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); | 632 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); |
| 564 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { | 633 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { |
| 565 super_type ^= FinalizeType( | 634 super_type ^= FinalizeType( |
| 566 cls, super_type, kFinalize, pending_types); | 635 cls, super_type, kFinalize, pending_types); |
| 567 cls.set_super_type(super_type); | 636 cls.set_super_type(super_type); |
| 568 } | 637 } |
| 569 TypeArguments& super_type_args = TypeArguments::Handle( | 638 TypeArguments& super_type_args = TypeArguments::Handle( |
| 570 super_type.arguments()); | 639 super_type.arguments()); |
| 571 // Offset of super type's type parameters in cls' type argument vector. | 640 // Offset of super type's type parameters in cls' type argument vector. |
| 572 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 641 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
| 573 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 642 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
| 574 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 643 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
| 575 if (!super_type_args.IsNull()) { | 644 if (!super_type_args.IsNull()) { |
| 576 super_type_arg = super_type_args.TypeAt(i); | 645 super_type_arg = super_type_args.TypeAt(i); |
| 577 if (!super_type_arg.IsFinalized()) { | 646 if (!super_type_arg.IsTypeRef()) { |
| 578 super_type_arg ^= FinalizeType( | 647 if (super_type_arg.IsBeingFinalized()) { |
| 579 cls, super_type_arg, kFinalize, pending_types); | 648 ASSERT(super_type_arg.IsType()); |
| 580 super_type_args.SetTypeAt(i, super_type_arg); | 649 CheckRecursiveType(cls, Type::Cast(super_type_arg), pending_types); |
| 650 if (FLAG_trace_type_finalization) { |
| 651 OS::Print("Creating TypeRef '%s' for class '%s'\n", |
| 652 String::Handle(super_type_arg.Name()).ToCString(), |
| 653 cls.ToCString()); |
| 654 } |
| 655 super_type_arg = TypeRef::New(super_type_arg); |
| 656 super_type_args.SetTypeAt(i, super_type_arg); |
| 657 } else { |
| 658 if (!super_type_arg.IsFinalized()) { |
| 659 super_type_arg ^= FinalizeType( |
| 660 cls, super_type_arg, kFinalize, pending_types); |
| 661 super_type_args.SetTypeAt(i, super_type_arg); |
| 662 // Note that super_type_arg may still not be finalized here, in |
| 663 // which case it is a TypeRef to a legal recursive type. |
| 664 // Therefore, it does not need to be instantiated below. |
| 665 // See tests/language/regress_16640_test.dart for an example. |
| 666 } |
| 667 } |
| 581 } | 668 } |
| 582 if (!super_type_arg.IsBeingFinalized() && | 669 if (!super_type_arg.IsBeingFinalized() && |
| 583 !super_type_arg.IsInstantiated()) { | 670 !super_type_arg.IsInstantiated()) { |
| 584 Error& error = Error::Handle(); | 671 Error& error = Error::Handle(); |
| 585 super_type_arg = super_type_arg.InstantiateFrom(arguments, &error); | 672 super_type_arg = |
| 673 super_type_arg.InstantiateFrom(arguments, &error, trail); |
| 586 if (!error.IsNull()) { | 674 if (!error.IsNull()) { |
| 587 // InstantiateFrom does not report an error if the type is still | 675 // InstantiateFrom does not report an error if the type is still |
| 588 // uninstantiated. Instead, it will return a new BoundedType so that | 676 // uninstantiated. Instead, it will return a new BoundedType so |
| 589 // the check is postponed to run time. | 677 // that the check is postponed to run time. |
| 590 ASSERT(super_type_arg.IsInstantiated()); | 678 ASSERT(super_type_arg.IsInstantiated()); |
| 591 // Keep only the first bound error. | 679 // Keep only the first bound error. |
| 592 if (bound_error->IsNull()) { | 680 if (bound_error->IsNull()) { |
| 593 *bound_error = error.raw(); | 681 *bound_error = error.raw(); |
| 594 } | 682 } |
| 595 } | 683 } |
| 596 } | 684 } |
| 597 } | 685 } |
| 598 arguments.SetTypeAt(i, super_type_arg); | 686 arguments.SetTypeAt(i, super_type_arg); |
| 599 } | 687 } |
| 600 FinalizeTypeArguments(super_class, arguments, super_offset, | 688 FinalizeTypeArguments(super_class, arguments, super_offset, |
| 601 bound_error, pending_types); | 689 bound_error, pending_types, trail); |
| 602 } | 690 } |
| 603 } | 691 } |
| 604 | 692 |
| 605 | 693 |
| 606 // Check the type argument vector 'arguments' against the corresponding bounds | 694 // Check the type argument vector 'arguments' against the corresponding bounds |
| 607 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 695 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
| 608 // Replace a type argument that cannot be checked at compile time by a | 696 // Replace a type argument that cannot be checked at compile time by a |
| 609 // BoundedType, thereby postponing the bound check to run time. | 697 // BoundedType, thereby postponing the bound check to run time. |
| 610 // Return a bound error if a type argument is not within bound at compile time. | 698 // Return a bound error if a type argument is not within bound at compile time. |
| 611 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, | 699 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 return type.raw(); | 844 return type.raw(); |
| 757 } | 845 } |
| 758 ASSERT(finalization >= kFinalize); | 846 ASSERT(finalization >= kFinalize); |
| 759 | 847 |
| 760 if (type.IsTypeRef()) { | 848 if (type.IsTypeRef()) { |
| 761 // The referenced type will be finalized later by the code that set the | 849 // The referenced type will be finalized later by the code that set the |
| 762 // is_being_finalized mark bit. | 850 // is_being_finalized mark bit. |
| 763 return type.raw(); | 851 return type.raw(); |
| 764 } | 852 } |
| 765 | 853 |
| 766 if (type.IsBeingFinalized()) { | 854 // Recursive types must be processed in FinalizeTypeArguments() and cannot be |
| 767 if (FLAG_trace_type_finalization) { | 855 // encountered here. |
| 768 OS::Print("Creating TypeRef '%s' for class '%s'\n", | 856 ASSERT(!type.IsBeingFinalized()); |
| 769 String::Handle(type.Name()).ToCString(), | 857 |
| 770 cls.ToCString()); | 858 // A malformed type gets mapped to a finalized type. |
| 771 } | 859 ResolveType(cls, type); |
| 772 return TypeRef::New(type); | 860 if (type.IsMalformed()) { |
| 861 ASSERT(type.IsFinalized()); |
| 862 return type.raw(); |
| 773 } | 863 } |
| 774 | 864 |
| 775 ResolveType(cls, type); | 865 Isolate* isolate = Isolate::Current(); |
| 776 if (FLAG_trace_type_finalization) { | 866 if (FLAG_trace_type_finalization) { |
| 777 OS::Print("Finalizing type '%s' for class '%s'\n", | 867 OS::Print("Finalizing type '%s' for class '%s'\n", |
| 778 String::Handle(type.Name()).ToCString(), | 868 String::Handle(isolate, type.Name()).ToCString(), |
| 779 cls.ToCString()); | 869 cls.ToCString()); |
| 780 } | 870 } |
| 781 | 871 |
| 782 if (type.IsTypeParameter()) { | 872 if (type.IsTypeParameter()) { |
| 783 const TypeParameter& type_parameter = TypeParameter::Cast(type); | 873 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
| 784 const Class& parameterized_class = | 874 const Class& parameterized_class = |
| 785 Class::Handle(type_parameter.parameterized_class()); | 875 Class::Handle(isolate, type_parameter.parameterized_class()); |
| 786 ASSERT(!parameterized_class.IsNull()); | 876 ASSERT(!parameterized_class.IsNull()); |
| 787 // The index must reflect the position of this type parameter in the type | 877 // The index must reflect the position of this type parameter in the type |
| 788 // arguments vector of its parameterized class. The offset to add is the | 878 // arguments vector of its parameterized class. The offset to add is the |
| 789 // number of type arguments in the super type, which is equal to the | 879 // number of type arguments in the super type, which is equal to the |
| 790 // difference in number of type arguments and type parameters of the | 880 // difference in number of type arguments and type parameters of the |
| 791 // parameterized class. | 881 // parameterized class. |
| 792 const intptr_t offset = parameterized_class.NumTypeArguments() - | 882 const intptr_t offset = parameterized_class.NumTypeArguments() - |
| 793 parameterized_class.NumTypeParameters(); | 883 parameterized_class.NumTypeParameters(); |
| 794 // Calling NumTypeParameters() may finalize this type parameter if it | 884 // Calling NumTypeParameters() may finalize this type parameter if it |
| 795 // belongs to a mixin application class. | 885 // belongs to a mixin application class. |
| 796 if (!type_parameter.IsFinalized()) { | 886 if (!type_parameter.IsFinalized()) { |
| 797 type_parameter.set_index(type_parameter.index() + offset); | 887 type_parameter.set_index(type_parameter.index() + offset); |
| 798 type_parameter.set_is_finalized(); | 888 type_parameter.set_is_finalized(); |
| 799 } else { | 889 } else { |
| 800 ASSERT(cls.IsMixinApplication()); | 890 ASSERT(cls.IsMixinApplication()); |
| 801 } | 891 } |
| 802 | 892 |
| 803 if (FLAG_trace_type_finalization) { | 893 if (FLAG_trace_type_finalization) { |
| 804 OS::Print("Done finalizing type parameter '%s' with index %" Pd "\n", | 894 OS::Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
| 805 String::Handle(type_parameter.name()).ToCString(), | 895 String::Handle(isolate, type_parameter.name()).ToCString(), |
| 806 type_parameter.index()); | 896 type_parameter.index()); |
| 807 } | 897 } |
| 808 | 898 |
| 809 // We do not canonicalize type parameters. | 899 // We do not canonicalize type parameters. |
| 810 return type_parameter.raw(); | 900 return type_parameter.raw(); |
| 811 } | 901 } |
| 812 | 902 |
| 813 // At this point, we can only have a parameterized_type. | 903 // At this point, we can only have a parameterized_type. |
| 814 const Type& parameterized_type = Type::Cast(type); | 904 const Type& parameterized_type = Type::Cast(type); |
| 815 | 905 |
| 816 Isolate* isolate = Isolate::Current(); | |
| 817 // This type is the root type of the type graph if no pending types queue is | 906 // This type is the root type of the type graph if no pending types queue is |
| 818 // allocated yet. | 907 // allocated yet. |
| 819 const bool is_root_type = (pending_types == NULL); | 908 const bool is_root_type = (pending_types == NULL); |
| 820 GrowableObjectArray& types = GrowableObjectArray::Handle(isolate); | 909 GrowableObjectArray& types = GrowableObjectArray::Handle(isolate); |
| 821 if (is_root_type) { | 910 if (is_root_type) { |
| 822 types = GrowableObjectArray::New(); | 911 types = GrowableObjectArray::New(); |
| 823 pending_types = &types; | 912 pending_types = &types; |
| 824 } | 913 } |
| 825 | 914 |
| 826 // The type class does not need to be finalized in order to finalize the type, | 915 // The type class does not need to be finalized in order to finalize the type, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 855 script, parameterized_type.token_pos(), | 944 script, parameterized_type.token_pos(), |
| 856 "wrong number of type arguments for class '%s'", | 945 "wrong number of type arguments for class '%s'", |
| 857 type_class_name.ToCString()); | 946 type_class_name.ToCString()); |
| 858 } | 947 } |
| 859 // Make the type raw and continue without reporting any error. | 948 // Make the type raw and continue without reporting any error. |
| 860 // A static warning should have been reported. | 949 // A static warning should have been reported. |
| 861 arguments = TypeArguments::null(); | 950 arguments = TypeArguments::null(); |
| 862 parameterized_type.set_arguments(arguments); | 951 parameterized_type.set_arguments(arguments); |
| 863 } | 952 } |
| 864 | 953 |
| 954 // Mark the type as being finalized in order to detect self reference and |
| 955 // postpone bound checking until after all types in the graph of |
| 956 // mutually recursive types are finalized. |
| 957 parameterized_type.set_is_being_finalized(); |
| 958 pending_types->Add(parameterized_type); |
| 959 |
| 865 // The full type argument vector consists of the type arguments of the | 960 // The full type argument vector consists of the type arguments of the |
| 866 // super types of type_class, which are initialized from the parsed | 961 // super types of type_class, which are initialized from the parsed |
| 867 // type arguments, followed by the parsed type arguments. | 962 // type arguments, followed by the parsed type arguments. |
| 868 TypeArguments& full_arguments = TypeArguments::Handle(isolate); | 963 TypeArguments& full_arguments = TypeArguments::Handle(isolate); |
| 869 Error& bound_error = Error::Handle(isolate); | 964 Error& bound_error = Error::Handle(isolate); |
| 870 if (num_type_arguments > 0) { | 965 if (num_type_arguments > 0) { |
| 871 // If no type arguments were parsed and if the super types do not prepend | 966 // If no type arguments were parsed and if the super types do not prepend |
| 872 // type arguments to the vector, we can leave the vector as null. | 967 // type arguments to the vector, we can leave the vector as null. |
| 873 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 968 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| 874 full_arguments = TypeArguments::New(num_type_arguments); | 969 full_arguments = TypeArguments::New(num_type_arguments); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 887 } | 982 } |
| 888 full_arguments.SetTypeAt(offset + i, type_arg); | 983 full_arguments.SetTypeAt(offset + i, type_arg); |
| 889 } | 984 } |
| 890 // Replace the compile-time argument vector (of length zero or | 985 // Replace the compile-time argument vector (of length zero or |
| 891 // num_type_parameters) of this type being finalized with the still | 986 // num_type_parameters) of this type being finalized with the still |
| 892 // unfinalized run-time argument vector (of length num_type_arguments). | 987 // unfinalized run-time argument vector (of length num_type_arguments). |
| 893 // This type being finalized may be recursively reached via bounds | 988 // This type being finalized may be recursively reached via bounds |
| 894 // checking, in which case type arguments of super classes will be seen | 989 // checking, in which case type arguments of super classes will be seen |
| 895 // as dynamic. | 990 // as dynamic. |
| 896 parameterized_type.set_arguments(full_arguments); | 991 parameterized_type.set_arguments(full_arguments); |
| 897 // Mark type as being finalized in order to detect self reference. | |
| 898 parameterized_type.set_is_being_finalized(); | |
| 899 // Finalize the current type arguments of the type, which are still the | 992 // Finalize the current type arguments of the type, which are still the |
| 900 // parsed type arguments. | 993 // parsed type arguments. |
| 901 if (!arguments.IsNull()) { | 994 if (!arguments.IsNull()) { |
| 902 for (intptr_t i = 0; i < num_type_parameters; i++) { | 995 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 903 type_arg = full_arguments.TypeAt(offset + i); | 996 type_arg = full_arguments.TypeAt(offset + i); |
| 904 ASSERT(!type_arg.IsBeingFinalized()); | 997 ASSERT(!type_arg.IsBeingFinalized()); |
| 905 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); | 998 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); |
| 906 if (type_arg.IsMalformed()) { | 999 if (type_arg.IsMalformed()) { |
| 907 // Malformed type arguments are mapped to dynamic. | 1000 // Malformed type arguments are mapped to dynamic. |
| 908 type_arg = Type::DynamicType(); | 1001 type_arg = Type::DynamicType(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 921 Class& owner_class = Class::Handle(isolate); | 1014 Class& owner_class = Class::Handle(isolate); |
| 922 if (type_class.IsSignatureClass()) { | 1015 if (type_class.IsSignatureClass()) { |
| 923 const Function& signature_fun = | 1016 const Function& signature_fun = |
| 924 Function::Handle(isolate, type_class.signature_function()); | 1017 Function::Handle(isolate, type_class.signature_function()); |
| 925 ASSERT(!signature_fun.is_static()); | 1018 ASSERT(!signature_fun.is_static()); |
| 926 owner_class = signature_fun.Owner(); | 1019 owner_class = signature_fun.Owner(); |
| 927 } else { | 1020 } else { |
| 928 owner_class = type_class.raw(); | 1021 owner_class = type_class.raw(); |
| 929 } | 1022 } |
| 930 if (offset > 0) { | 1023 if (offset > 0) { |
| 1024 GrowableObjectArray& trail = |
| 1025 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
| 931 FinalizeTypeArguments(owner_class, full_arguments, offset, | 1026 FinalizeTypeArguments(owner_class, full_arguments, offset, |
| 932 &bound_error, pending_types); | 1027 &bound_error, pending_types, &trail); |
| 933 } | 1028 } |
| 934 if (full_arguments.IsRaw(0, num_type_arguments)) { | 1029 if (full_arguments.IsRaw(0, num_type_arguments)) { |
| 935 // The parameterized_type is raw. Set its argument vector to null, which | 1030 // The parameterized_type is raw. Set its argument vector to null, which |
| 936 // is more efficient in type tests. | 1031 // is more efficient in type tests. |
| 937 full_arguments = TypeArguments::null(); | 1032 full_arguments = TypeArguments::null(); |
| 938 } else { | |
| 939 // Postpone bound checking until after all types in the graph of | |
| 940 // mutually recursive types are finalized. | |
| 941 pending_types->Add(parameterized_type); | |
| 942 } | 1033 } |
| 943 parameterized_type.set_arguments(full_arguments); | 1034 parameterized_type.set_arguments(full_arguments); |
| 944 } else { | 1035 } else { |
| 945 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 1036 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
| 946 } | 1037 } |
| 947 } | 1038 } |
| 948 | 1039 |
| 949 // Self referencing types may get finalized indirectly. | 1040 // Self referencing types may get finalized indirectly. |
| 950 if (!parameterized_type.IsFinalized()) { | 1041 if (!parameterized_type.IsFinalized()) { |
| 951 ASSERT(full_arguments.IsNull() || | 1042 ASSERT(full_arguments.IsNull() || |
| 952 !full_arguments.IsRaw(0, num_type_arguments)); | 1043 !full_arguments.IsRaw(0, num_type_arguments)); |
| 953 // Mark the type as finalized. | 1044 // Mark the type as finalized. |
| 954 parameterized_type.SetIsFinalized(); | 1045 parameterized_type.SetIsFinalized(); |
| 1046 // Do not yet remove the type from the pending_types array. |
| 955 } | 1047 } |
| 956 | 1048 |
| 957 // If we are done finalizing a graph of mutually recursive types, check their | 1049 // If we are done finalizing a graph of mutually recursive types, check their |
| 958 // bounds. | 1050 // bounds. |
| 959 if (is_root_type) { | 1051 if (is_root_type) { |
| 960 Type& type = Type::Handle(isolate); | 1052 Type& type = Type::Handle(isolate); |
| 961 for (intptr_t i = 0; i < types.Length(); i++) { | 1053 for (intptr_t i = 0; i < types.Length(); i++) { |
| 962 type ^= types.At(i); | 1054 type ^= types.At(i); |
| 963 CheckTypeBounds(cls, type); | 1055 CheckTypeBounds(cls, type); |
| 964 } | 1056 } |
| (...skipping 1415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2380 collected_args.Add(arg); | 2472 collected_args.Add(arg); |
| 2381 } | 2473 } |
| 2382 } | 2474 } |
| 2383 | 2475 |
| 2384 | 2476 |
| 2385 RawType* ClassFinalizer::ResolveMixinAppType( | 2477 RawType* ClassFinalizer::ResolveMixinAppType( |
| 2386 const Class& cls, | 2478 const Class& cls, |
| 2387 const MixinAppType& mixin_app_type) { | 2479 const MixinAppType& mixin_app_type) { |
| 2388 // Lookup or create mixin application classes in the library of cls | 2480 // Lookup or create mixin application classes in the library of cls |
| 2389 // and resolve super type and mixin types. | 2481 // and resolve super type and mixin types. |
| 2390 const Library& library = Library::Handle(cls.library()); | 2482 Isolate* isolate = Isolate::Current(); |
| 2483 const Library& library = Library::Handle(isolate, cls.library()); |
| 2391 ASSERT(!library.IsNull()); | 2484 ASSERT(!library.IsNull()); |
| 2392 const Script& script = Script::Handle(cls.script()); | 2485 const Script& script = Script::Handle(isolate, cls.script()); |
| 2393 ASSERT(!script.IsNull()); | 2486 ASSERT(!script.IsNull()); |
| 2394 const GrowableObjectArray& type_args = | 2487 const GrowableObjectArray& type_args = |
| 2395 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2488 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
| 2396 AbstractType& mixin_super_type = | 2489 AbstractType& mixin_super_type = |
| 2397 AbstractType::Handle(mixin_app_type.super_type()); | 2490 AbstractType::Handle(isolate, mixin_app_type.super_type()); |
| 2398 ResolveType(cls, mixin_super_type); | 2491 ResolveType(cls, mixin_super_type); |
| 2399 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. | 2492 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
| 2400 // The super type may have a BoundedType as type argument, but cannot be | 2493 // The super type may have a BoundedType as type argument, but cannot be |
| 2401 // a BoundedType itself. | 2494 // a BoundedType itself. |
| 2402 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2495 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
| 2403 AbstractType& mixin_type = AbstractType::Handle(); | 2496 AbstractType& mixin_type = AbstractType::Handle(isolate); |
| 2404 Type& generic_mixin_type = Type::Handle(); | 2497 Type& generic_mixin_type = Type::Handle(isolate); |
| 2405 Class& mixin_type_class = Class::Handle(); | 2498 Class& mixin_type_class = Class::Handle(isolate); |
| 2406 Class& mixin_app_class = Class::Handle(); | 2499 Class& mixin_app_class = Class::Handle(isolate); |
| 2407 String& mixin_app_class_name = String::Handle(); | 2500 String& mixin_app_class_name = String::Handle(isolate); |
| 2408 String& mixin_type_class_name = String::Handle(); | 2501 String& mixin_type_class_name = String::Handle(isolate); |
| 2409 AbstractType& super_type_arg = AbstractType::Handle(); | 2502 AbstractType& super_type_arg = AbstractType::Handle(isolate); |
| 2410 AbstractType& mixin_type_arg = AbstractType::Handle(); | 2503 AbstractType& mixin_type_arg = AbstractType::Handle(isolate); |
| 2411 const intptr_t depth = mixin_app_type.Depth(); | 2504 const intptr_t depth = mixin_app_type.Depth(); |
| 2412 for (intptr_t i = 0; i < depth; i++) { | 2505 for (intptr_t i = 0; i < depth; i++) { |
| 2413 mixin_type = mixin_app_type.MixinTypeAt(i); | 2506 mixin_type = mixin_app_type.MixinTypeAt(i); |
| 2414 ASSERT(!mixin_type.IsNull()); | 2507 ASSERT(!mixin_type.IsNull()); |
| 2415 ResolveType(cls, mixin_type); | 2508 ResolveType(cls, mixin_type); |
| 2416 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. | 2509 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
| 2417 ASSERT(mixin_type.IsType()); | 2510 ASSERT(mixin_type.IsType()); |
| 2418 const intptr_t num_super_type_args = type_args.Length(); | 2511 const intptr_t num_super_type_args = type_args.Length(); |
| 2419 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2512 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
| 2420 | 2513 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2462 mixin_type.token_pos()); | 2555 mixin_type.token_pos()); |
| 2463 mixin_app_class.set_super_type(mixin_super_type); | 2556 mixin_app_class.set_super_type(mixin_super_type); |
| 2464 mixin_type_class = mixin_type.type_class(); | 2557 mixin_type_class = mixin_type.type_class(); |
| 2465 generic_mixin_type = Type::New(mixin_type_class, | 2558 generic_mixin_type = Type::New(mixin_type_class, |
| 2466 Object::null_type_arguments(), | 2559 Object::null_type_arguments(), |
| 2467 mixin_type.token_pos()); | 2560 mixin_type.token_pos()); |
| 2468 mixin_app_class.set_mixin(generic_mixin_type); | 2561 mixin_app_class.set_mixin(generic_mixin_type); |
| 2469 // Add the mixin type to the list of interfaces that the mixin application | 2562 // Add the mixin type to the list of interfaces that the mixin application |
| 2470 // class implements. This is necessary so that cycle check work at | 2563 // class implements. This is necessary so that cycle check work at |
| 2471 // compile time (type arguments are ignored by that check). | 2564 // compile time (type arguments are ignored by that check). |
| 2472 const Array& interfaces = Array::Handle(Array::New(1)); | 2565 const Array& interfaces = Array::Handle(isolate, Array::New(1)); |
| 2473 interfaces.SetAt(0, generic_mixin_type); | 2566 interfaces.SetAt(0, generic_mixin_type); |
| 2474 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | 2567 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
| 2475 mixin_app_class.set_interfaces(interfaces); | 2568 mixin_app_class.set_interfaces(interfaces); |
| 2476 mixin_app_class.set_is_synthesized_class(); | 2569 mixin_app_class.set_is_synthesized_class(); |
| 2477 library.AddClass(mixin_app_class); | 2570 library.AddClass(mixin_app_class); |
| 2478 | 2571 |
| 2479 // No need to add the new class to pending_classes, since it will be | 2572 // No need to add the new class to pending_classes, since it will be |
| 2480 // processed via the super_type chain of a pending class. | 2573 // processed via the super_type chain of a pending class. |
| 2481 | 2574 |
| 2482 if (FLAG_trace_class_finalization) { | 2575 if (FLAG_trace_class_finalization) { |
| 2483 OS::Print("Creating mixin application %s\n", | 2576 OS::Print("Creating mixin application %s\n", |
| 2484 mixin_app_class.ToCString()); | 2577 mixin_app_class.ToCString()); |
| 2485 } | 2578 } |
| 2486 } | 2579 } |
| 2487 // This mixin application class becomes the type class of the super type of | 2580 // This mixin application class becomes the type class of the super type of |
| 2488 // the next mixin application class. It is however too early to provide the | 2581 // the next mixin application class. It is however too early to provide the |
| 2489 // correct super type arguments. We use the raw type for now. | 2582 // correct super type arguments. We use the raw type for now. |
| 2490 mixin_super_type = Type::New(mixin_app_class, | 2583 mixin_super_type = Type::New(mixin_app_class, |
| 2491 Object::null_type_arguments(), | 2584 Object::null_type_arguments(), |
| 2492 mixin_type.token_pos()); | 2585 mixin_type.token_pos()); |
| 2493 } | 2586 } |
| 2494 AbstractType& type_arg = AbstractType::Handle(); | 2587 TypeArguments& mixin_app_args = TypeArguments::Handle(isolate); |
| 2495 const TypeArguments& mixin_app_args = | 2588 if (type_args.Length() > 0) { |
| 2496 TypeArguments::Handle(TypeArguments::New(type_args.Length())); | 2589 mixin_app_args = TypeArguments::New(type_args.Length()); |
| 2497 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2590 AbstractType& type_arg = AbstractType::Handle(isolate); |
| 2498 type_arg ^= type_args.At(i); | 2591 for (intptr_t i = 0; i < type_args.Length(); i++) { |
| 2499 mixin_app_args.SetTypeAt(i, type_arg); | 2592 type_arg ^= type_args.At(i); |
| 2593 mixin_app_args.SetTypeAt(i, type_arg); |
| 2594 } |
| 2500 } | 2595 } |
| 2501 if (FLAG_trace_class_finalization) { | 2596 if (FLAG_trace_class_finalization) { |
| 2502 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", | 2597 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", |
| 2503 mixin_app_args.ToCString()); | 2598 mixin_app_args.ToCString()); |
| 2504 } | 2599 } |
| 2505 // The mixin application class at depth k is a subclass of mixin application | 2600 // The mixin application class at depth k is a subclass of mixin application |
| 2506 // class at depth k - 1. Build a new super type with the class at the highest | 2601 // class at depth k - 1. Build a new super type with the class at the highest |
| 2507 // depth (the last one processed by the loop above) as the type class and the | 2602 // depth (the last one processed by the loop above) as the type class and the |
| 2508 // collected type arguments from the super type and all mixin types. | 2603 // collected type arguments from the super type and all mixin types. |
| 2509 // This super type replaces the MixinAppType object in the class that extends | 2604 // This super type replaces the MixinAppType object in the class that extends |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2521 // we found a loop. | 2616 // we found a loop. |
| 2522 void ClassFinalizer::ResolveSuperTypeAndInterfaces( | 2617 void ClassFinalizer::ResolveSuperTypeAndInterfaces( |
| 2523 const Class& cls, GrowableArray<intptr_t>* visited) { | 2618 const Class& cls, GrowableArray<intptr_t>* visited) { |
| 2524 if (cls.is_cycle_free()) { | 2619 if (cls.is_cycle_free()) { |
| 2525 return; | 2620 return; |
| 2526 } | 2621 } |
| 2527 ASSERT(visited != NULL); | 2622 ASSERT(visited != NULL); |
| 2528 if (FLAG_trace_class_finalization) { | 2623 if (FLAG_trace_class_finalization) { |
| 2529 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); | 2624 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); |
| 2530 } | 2625 } |
| 2626 Isolate* isolate = Isolate::Current(); |
| 2531 const intptr_t cls_index = cls.id(); | 2627 const intptr_t cls_index = cls.id(); |
| 2532 for (intptr_t i = 0; i < visited->length(); i++) { | 2628 for (intptr_t i = 0; i < visited->length(); i++) { |
| 2533 if ((*visited)[i] == cls_index) { | 2629 if ((*visited)[i] == cls_index) { |
| 2534 // We have already visited class 'cls'. We found a cycle. | 2630 // We have already visited class 'cls'. We found a cycle. |
| 2535 const String& class_name = String::Handle(cls.Name()); | 2631 const String& class_name = String::Handle(isolate, cls.Name()); |
| 2536 const Script& script = Script::Handle(cls.script()); | 2632 const Script& script = Script::Handle(isolate, cls.script()); |
| 2537 ReportError(Error::Handle(), // No previous error. | 2633 ReportError(Error::Handle(isolate), // No previous error. |
| 2538 script, cls.token_pos(), | 2634 script, cls.token_pos(), |
| 2539 "cyclic reference found for class '%s'", | 2635 "cyclic reference found for class '%s'", |
| 2540 class_name.ToCString()); | 2636 class_name.ToCString()); |
| 2541 } | 2637 } |
| 2542 } | 2638 } |
| 2543 | 2639 |
| 2544 // If the class/interface has no explicit super class/interfaces | 2640 // If the class/interface has no explicit super class/interfaces |
| 2545 // and is not a mixin application, we are done. | 2641 // and is not a mixin application, we are done. |
| 2546 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 2642 AbstractType& super_type = AbstractType::Handle(isolate, cls.super_type()); |
| 2547 Array& super_interfaces = Array::Handle(cls.interfaces()); | 2643 Array& super_interfaces = Array::Handle(isolate, cls.interfaces()); |
| 2548 if ((super_type.IsNull() || super_type.IsObjectType()) && | 2644 if ((super_type.IsNull() || super_type.IsObjectType()) && |
| 2549 (super_interfaces.Length() == 0)) { | 2645 (super_interfaces.Length() == 0)) { |
| 2550 cls.set_is_cycle_free(); | 2646 cls.set_is_cycle_free(); |
| 2551 return; | 2647 return; |
| 2552 } | 2648 } |
| 2553 | 2649 |
| 2554 if (super_type.IsMixinAppType()) { | 2650 if (super_type.IsMixinAppType()) { |
| 2555 // For the cycle check below to work, ResolveMixinAppType needs to set | 2651 // For the cycle check below to work, ResolveMixinAppType needs to set |
| 2556 // the mixin interfaces in the super classes, even if only in raw form. | 2652 // the mixin interfaces in the super classes, even if only in raw form. |
| 2557 // It is indeed too early to set the correct type arguments, which is not | 2653 // It is indeed too early to set the correct type arguments, which is not |
| 2558 // a problem since they are ignored in the cycle check. | 2654 // a problem since they are ignored in the cycle check. |
| 2559 const MixinAppType& mixin_app_type = MixinAppType::Cast(super_type); | 2655 const MixinAppType& mixin_app_type = MixinAppType::Cast(super_type); |
| 2560 super_type = ResolveMixinAppType(cls, mixin_app_type); | 2656 super_type = ResolveMixinAppType(cls, mixin_app_type); |
| 2561 cls.set_super_type(super_type); | 2657 cls.set_super_type(super_type); |
| 2562 } | 2658 } |
| 2563 | 2659 |
| 2564 // If cls belongs to core lib, restrictions about allowed interfaces | 2660 // If cls belongs to core lib, restrictions about allowed interfaces |
| 2565 // are lifted. | 2661 // are lifted. |
| 2566 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); | 2662 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); |
| 2567 | 2663 |
| 2568 // Resolve and check the super type and interfaces of cls. | 2664 // Resolve and check the super type and interfaces of cls. |
| 2569 visited->Add(cls_index); | 2665 visited->Add(cls_index); |
| 2570 AbstractType& interface = AbstractType::Handle(); | 2666 AbstractType& interface = AbstractType::Handle(isolate); |
| 2571 Class& interface_class = Class::Handle(); | 2667 Class& interface_class = Class::Handle(isolate); |
| 2572 | 2668 |
| 2573 // Resolve super type. Failures lead to a longjmp. | 2669 // Resolve super type. Failures lead to a longjmp. |
| 2574 ResolveType(cls, super_type); | 2670 ResolveType(cls, super_type); |
| 2575 if (super_type.IsMalformedOrMalbounded()) { | 2671 if (super_type.IsMalformedOrMalbounded()) { |
| 2576 ReportError(Error::Handle(super_type.error())); | 2672 ReportError(Error::Handle(isolate, super_type.error())); |
| 2577 } | 2673 } |
| 2578 if (super_type.IsDynamicType()) { | 2674 if (super_type.IsDynamicType()) { |
| 2579 const Script& script = Script::Handle(cls.script()); | 2675 const Script& script = Script::Handle(isolate, cls.script()); |
| 2580 ReportError(Error::Handle(), // No previous error. | 2676 ReportError(Error::Handle(isolate), // No previous error. |
| 2581 script, cls.token_pos(), | 2677 script, cls.token_pos(), |
| 2582 "class '%s' may not extend 'dynamic'", | 2678 "class '%s' may not extend 'dynamic'", |
| 2583 String::Handle(cls.Name()).ToCString()); | 2679 String::Handle(isolate, cls.Name()).ToCString()); |
| 2584 } | 2680 } |
| 2585 interface_class = super_type.type_class(); | 2681 interface_class = super_type.type_class(); |
| 2586 if (interface_class.IsSignatureClass()) { | 2682 if (interface_class.IsSignatureClass()) { |
| 2587 const Script& script = Script::Handle(cls.script()); | 2683 const Script& script = Script::Handle(isolate, cls.script()); |
| 2588 ReportError(Error::Handle(), // No previous error. | 2684 ReportError(Error::Handle(isolate), // No previous error. |
| 2589 script, cls.token_pos(), | 2685 script, cls.token_pos(), |
| 2590 "class '%s' may not extend function type alias '%s'", | 2686 "class '%s' may not extend function type alias '%s'", |
| 2591 String::Handle(cls.Name()).ToCString(), | 2687 String::Handle(isolate, cls.Name()).ToCString(), |
| 2592 String::Handle(super_type.UserVisibleName()).ToCString()); | 2688 String::Handle(isolate, |
| 2689 super_type.UserVisibleName()).ToCString()); |
| 2593 } | 2690 } |
| 2594 | 2691 |
| 2595 // If cls belongs to core lib or to core lib's implementation, restrictions | 2692 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 2596 // about allowed interfaces are lifted. | 2693 // about allowed interfaces are lifted. |
| 2597 if (!cls_belongs_to_core_lib) { | 2694 if (!cls_belongs_to_core_lib) { |
| 2598 // Prevent extending core implementation classes. | 2695 // Prevent extending core implementation classes. |
| 2599 bool is_error = false; | 2696 bool is_error = false; |
| 2600 switch (interface_class.id()) { | 2697 switch (interface_class.id()) { |
| 2601 case kNumberCid: | 2698 case kNumberCid: |
| 2602 case kIntegerCid: // Class Integer, not int. | 2699 case kIntegerCid: // Class Integer, not int. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2627 // Special case: classes for which we don't have a known class id. | 2724 // Special case: classes for which we don't have a known class id. |
| 2628 if (super_type.IsDoubleType() || | 2725 if (super_type.IsDoubleType() || |
| 2629 super_type.IsIntType() || | 2726 super_type.IsIntType() || |
| 2630 super_type.IsStringType()) { | 2727 super_type.IsStringType()) { |
| 2631 is_error = true; | 2728 is_error = true; |
| 2632 } | 2729 } |
| 2633 break; | 2730 break; |
| 2634 } | 2731 } |
| 2635 } | 2732 } |
| 2636 if (is_error) { | 2733 if (is_error) { |
| 2637 const Script& script = Script::Handle(cls.script()); | 2734 const Script& script = Script::Handle(isolate, cls.script()); |
| 2638 ReportError(Error::Handle(), // No previous error. | 2735 ReportError(Error::Handle(isolate), // No previous error. |
| 2639 script, cls.token_pos(), | 2736 script, cls.token_pos(), |
| 2640 "'%s' is not allowed to extend '%s'", | 2737 "'%s' is not allowed to extend '%s'", |
| 2641 String::Handle(cls.Name()).ToCString(), | 2738 String::Handle(isolate, cls.Name()).ToCString(), |
| 2642 String::Handle(interface_class.Name()).ToCString()); | 2739 String::Handle(isolate, interface_class.Name()).ToCString()); |
| 2643 } | 2740 } |
| 2644 } | 2741 } |
| 2645 // Now resolve the super interfaces of the super type. | 2742 // Now resolve the super interfaces of the super type. |
| 2646 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2743 ResolveSuperTypeAndInterfaces(interface_class, visited); |
| 2647 | 2744 |
| 2648 // Resolve interfaces. Failures lead to a longjmp. | 2745 // Resolve interfaces. Failures lead to a longjmp. |
| 2649 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 2746 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 2650 interface ^= super_interfaces.At(i); | 2747 interface ^= super_interfaces.At(i); |
| 2651 ResolveType(cls, interface); | 2748 ResolveType(cls, interface); |
| 2652 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 2749 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
| 2653 // A malbounded interface is only reported when involved in a type test. | 2750 // A malbounded interface is only reported when involved in a type test. |
| 2654 if (interface.IsMalformed()) { | 2751 if (interface.IsMalformed()) { |
| 2655 ReportError(Error::Handle(interface.error())); | 2752 ReportError(Error::Handle(isolate, interface.error())); |
| 2656 } | 2753 } |
| 2657 if (interface.IsDynamicType()) { | 2754 if (interface.IsDynamicType()) { |
| 2658 const Script& script = Script::Handle(cls.script()); | 2755 const Script& script = Script::Handle(isolate, cls.script()); |
| 2659 ReportError(Error::Handle(), // No previous error. | 2756 ReportError(Error::Handle(isolate), // No previous error. |
| 2660 script, cls.token_pos(), | 2757 script, cls.token_pos(), |
| 2661 "'dynamic' may not be used as interface"); | 2758 "'dynamic' may not be used as interface"); |
| 2662 } | 2759 } |
| 2663 interface_class = interface.type_class(); | 2760 interface_class = interface.type_class(); |
| 2664 if (interface_class.IsSignatureClass()) { | 2761 if (interface_class.IsSignatureClass()) { |
| 2665 const Script& script = Script::Handle(cls.script()); | 2762 const Script& script = Script::Handle(isolate, cls.script()); |
| 2666 ReportError(Error::Handle(), // No previous error. | 2763 ReportError(Error::Handle(isolate), // No previous error. |
| 2667 script, cls.token_pos(), | 2764 script, cls.token_pos(), |
| 2668 "function type alias '%s' may not be used as interface", | 2765 "function type alias '%s' may not be used as interface", |
| 2669 String::Handle(interface_class.Name()).ToCString()); | 2766 String::Handle(isolate, interface_class.Name()).ToCString()); |
| 2670 } | 2767 } |
| 2671 // Verify that unless cls belongs to core lib, it cannot extend, implement, | 2768 // Verify that unless cls belongs to core lib, it cannot extend, implement, |
| 2672 // or mixin any of Null, bool, num, int, double, String, dynamic. | 2769 // or mixin any of Null, bool, num, int, double, String, dynamic. |
| 2673 if (!cls_belongs_to_core_lib) { | 2770 if (!cls_belongs_to_core_lib) { |
| 2674 if (interface.IsBoolType() || | 2771 if (interface.IsBoolType() || |
| 2675 interface.IsNullType() || | 2772 interface.IsNullType() || |
| 2676 interface.IsNumberType() || | 2773 interface.IsNumberType() || |
| 2677 interface.IsIntType() || | 2774 interface.IsIntType() || |
| 2678 interface.IsDoubleType() || | 2775 interface.IsDoubleType() || |
| 2679 interface.IsStringType() || | 2776 interface.IsStringType() || |
| 2680 interface.IsDynamicType()) { | 2777 interface.IsDynamicType()) { |
| 2681 const Script& script = Script::Handle(cls.script()); | 2778 const Script& script = Script::Handle(isolate, cls.script()); |
| 2682 const String& interface_name = String::Handle(interface_class.Name()); | 2779 const String& interface_name = String::Handle(isolate, |
| 2780 interface_class.Name()); |
| 2683 if (cls.IsMixinApplication()) { | 2781 if (cls.IsMixinApplication()) { |
| 2684 ReportError(Error::Handle(), // No previous error. | 2782 ReportError(Error::Handle(isolate), // No previous error. |
| 2685 script, cls.token_pos(), | 2783 script, cls.token_pos(), |
| 2686 "illegal mixin of '%s'", | 2784 "illegal mixin of '%s'", |
| 2687 interface_name.ToCString()); | 2785 interface_name.ToCString()); |
| 2688 } else { | 2786 } else { |
| 2689 ReportError(Error::Handle(), // No previous error. | 2787 ReportError(Error::Handle(isolate), // No previous error. |
| 2690 script, cls.token_pos(), | 2788 script, cls.token_pos(), |
| 2691 "'%s' is not allowed to extend or implement '%s'", | 2789 "'%s' is not allowed to extend or implement '%s'", |
| 2692 String::Handle(cls.Name()).ToCString(), | 2790 String::Handle(isolate, cls.Name()).ToCString(), |
| 2693 interface_name.ToCString()); | 2791 interface_name.ToCString()); |
| 2694 } | 2792 } |
| 2695 } | 2793 } |
| 2696 } | 2794 } |
| 2697 interface_class.set_is_implemented(); | 2795 interface_class.set_is_implemented(); |
| 2698 // Now resolve the super interfaces. | 2796 // Now resolve the super interfaces. |
| 2699 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2797 ResolveSuperTypeAndInterfaces(interface_class, visited); |
| 2700 } | 2798 } |
| 2701 visited->RemoveLast(); | 2799 visited->RemoveLast(); |
| 2702 cls.set_is_cycle_free(); | 2800 cls.set_is_cycle_free(); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2931 expected_name ^= String::New("_offset"); | 3029 expected_name ^= String::New("_offset"); |
| 2932 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3030 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2933 field ^= fields_array.At(2); | 3031 field ^= fields_array.At(2); |
| 2934 ASSERT(field.Offset() == TypedDataView::length_offset()); | 3032 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2935 name ^= field.name(); | 3033 name ^= field.name(); |
| 2936 ASSERT(name.Equals("length")); | 3034 ASSERT(name.Equals("length")); |
| 2937 #endif | 3035 #endif |
| 2938 } | 3036 } |
| 2939 | 3037 |
| 2940 } // namespace dart | 3038 } // namespace dart |
| OLD | NEW |