| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 AbstractTypeArguments::Handle(parameterized_type.arguments()); | 681 AbstractTypeArguments::Handle(parameterized_type.arguments()); |
| 682 if (!arguments.IsNull()) { | 682 if (!arguments.IsNull()) { |
| 683 intptr_t num_arguments = arguments.Length(); | 683 intptr_t num_arguments = arguments.Length(); |
| 684 for (intptr_t i = 0; i < num_arguments; i++) { | 684 for (intptr_t i = 0; i < num_arguments; i++) { |
| 685 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); | 685 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
| 686 type_argument = FinalizeType(cls, type_argument, finalization); | 686 type_argument = FinalizeType(cls, type_argument, finalization); |
| 687 arguments.SetTypeAt(i, type_argument); | 687 arguments.SetTypeAt(i, type_argument); |
| 688 } | 688 } |
| 689 } | 689 } |
| 690 | 690 |
| 691 // If the type class is a signature class, we are finalizing its signature | |
| 692 // type, thereby finalizing the result type and parameter types of its | |
| 693 // signature function. | |
| 694 // Do this before marking this type as finalized in order to detect cycles. | |
| 695 if (type_class.IsSignatureClass()) { | |
| 696 // Signature classes are finalized upon creation. | |
| 697 ASSERT(type_class.is_finalized()); | |
| 698 // Resolve and finalize the result and parameter types of the signature | |
| 699 // function of this signature class. | |
| 700 ResolveAndFinalizeSignature( | |
| 701 type_class, Function::Handle(type_class.signature_function())); | |
| 702 } | |
| 703 | |
| 704 // Illegally self referencing function types may get finalized indirectly. | |
| 705 if (parameterized_type.IsFinalized()) { | |
| 706 ASSERT(parameterized_type.IsMalformed()); | |
| 707 return parameterized_type.raw(); | |
| 708 } | |
| 709 | |
| 710 // The finalized type argument vector needs num_type_arguments types. | 691 // The finalized type argument vector needs num_type_arguments types. |
| 711 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 692 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 712 // The type class has num_type_parameters type parameters. | 693 // The type class has num_type_parameters type parameters. |
| 713 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 694 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 714 | 695 |
| 715 // Initialize the type argument vector. | 696 // Initialize the type argument vector. |
| 716 // Check the number of parsed type arguments, if any. | 697 // Check the number of parsed type arguments, if any. |
| 717 // Specifying no type arguments indicates a raw type, which is not an error. | 698 // Specifying no type arguments indicates a raw type, which is not an error. |
| 718 // However, type parameter bounds are checked below, even for a raw type. | 699 // However, type parameter bounds are checked below, even for a raw type. |
| 719 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 700 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 720 // Wrong number of type arguments. The type is malformed. | 701 // Wrong number of type arguments. The type is malformed. |
| 721 FinalizeMalformedType( | 702 FinalizeMalformedType( |
| 722 Error::Handle(), // No previous error. | 703 Error::Handle(), // No previous error. |
| 723 cls, parameterized_type, finalization, | 704 cls, parameterized_type, finalization, |
| 724 "wrong number of type arguments in type '%s'", | 705 "wrong number of type arguments in type '%s'", |
| 725 String::Handle(parameterized_type.Name()).ToCString()); | 706 String::Handle(parameterized_type.Name()).ToCString()); |
| 726 return parameterized_type.raw(); | 707 return parameterized_type.raw(); |
| 727 } | 708 } |
| 728 // The full type argument vector consists of the type arguments of the | 709 // The full type argument vector consists of the type arguments of the |
| 729 // super types of type_class, which may be initialized from the parsed | 710 // super types of type_class, which may be initialized from the parsed |
| 730 // type arguments, followed by the parsed type arguments. | 711 // type arguments, followed by the parsed type arguments. |
| 712 TypeArguments& full_arguments = TypeArguments::Handle(); |
| 731 if (num_type_arguments > 0) { | 713 if (num_type_arguments > 0) { |
| 732 TypeArguments& full_arguments = TypeArguments::Handle(); | |
| 733 // If no type arguments were parsed and if the super types do not prepend | 714 // If no type arguments were parsed and if the super types do not prepend |
| 734 // type arguments to the vector, we can leave the vector as null. | 715 // type arguments to the vector, we can leave the vector as null. |
| 735 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 716 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| 736 full_arguments = TypeArguments::New(num_type_arguments); | 717 full_arguments = TypeArguments::New(num_type_arguments); |
| 737 // Copy the parsed type arguments at the correct offset in the full type | 718 // Copy the parsed type arguments at the correct offset in the full type |
| 738 // argument vector. | 719 // argument vector. |
| 739 const intptr_t offset = num_type_arguments - num_type_parameters; | 720 const intptr_t offset = num_type_arguments - num_type_parameters; |
| 740 AbstractType& type_arg = AbstractType::Handle(Type::DynamicType()); | 721 AbstractType& type_arg = AbstractType::Handle(Type::DynamicType()); |
| 741 for (intptr_t i = 0; i < num_type_parameters; i++) { | 722 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 742 // If no type parameters were provided, a raw type is desired, so we | 723 // If no type parameters were provided, a raw type is desired, so we |
| (...skipping 19 matching lines...) Expand all Loading... |
| 762 full_arguments = TypeArguments::null(); | 743 full_arguments = TypeArguments::null(); |
| 763 } else { | 744 } else { |
| 764 // FinalizeTypeArguments can modify 'full_arguments', | 745 // FinalizeTypeArguments can modify 'full_arguments', |
| 765 // canonicalize afterwards. | 746 // canonicalize afterwards. |
| 766 full_arguments ^= full_arguments.Canonicalize(); | 747 full_arguments ^= full_arguments.Canonicalize(); |
| 767 } | 748 } |
| 768 parameterized_type.set_arguments(full_arguments); | 749 parameterized_type.set_arguments(full_arguments); |
| 769 } else { | 750 } else { |
| 770 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 751 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
| 771 } | 752 } |
| 772 // Mark the type as finalized. | 753 } |
| 773 if (parameterized_type.IsInstantiated()) { | |
| 774 parameterized_type.set_is_finalized_instantiated(); | |
| 775 } else { | |
| 776 parameterized_type.set_is_finalized_uninstantiated(); | |
| 777 } | |
| 778 | 754 |
| 779 // Upper bounds of the finalized type arguments are only verified in checked | 755 // Illegally self referencing types may get finalized indirectly. |
| 780 // mode, since bound errors are never reported by the vm in production mode. | 756 if (parameterized_type.IsFinalized()) { |
| 781 if (FLAG_enable_type_checks && | 757 ASSERT(parameterized_type.IsMalformed()); |
| 782 !full_arguments.IsNull() && | |
| 783 full_arguments.IsInstantiated()) { | |
| 784 ResolveAndFinalizeUpperBounds(type_class); | |
| 785 Error& malformed_error = Error::Handle(); | |
| 786 // Pass the full type argument vector as the bounds instantiator. | |
| 787 if (!full_arguments.IsWithinBoundsOf(type_class, | |
| 788 full_arguments, | |
| 789 &malformed_error)) { | |
| 790 ASSERT(!malformed_error.IsNull()); | |
| 791 // The type argument vector of the type is not within bounds. The type | |
| 792 // is malformed. Prepend malformed_error to new malformed type error in | |
| 793 // order to report both locations. | |
| 794 // Note that malformed bounds never result in a compile time error, even | |
| 795 // in checked mode. Therefore, overwrite finalization with kFinalize | |
| 796 // when finalizing the malformed type. | |
| 797 FinalizeMalformedType( | |
| 798 malformed_error, | |
| 799 cls, parameterized_type, kFinalize, | |
| 800 "type arguments of type '%s' are not within bounds", | |
| 801 String::Handle(parameterized_type.Name()).ToCString()); | |
| 802 return parameterized_type.raw(); | |
| 803 } | |
| 804 } | |
| 805 } else { | 758 } else { |
| 806 // Mark the type as finalized. | 759 // Mark the type as finalized. |
| 807 if (parameterized_type.IsInstantiated()) { | 760 if (parameterized_type.IsInstantiated()) { |
| 808 parameterized_type.set_is_finalized_instantiated(); | 761 parameterized_type.set_is_finalized_instantiated(); |
| 809 } else { | 762 } else { |
| 810 parameterized_type.set_is_finalized_uninstantiated(); | 763 parameterized_type.set_is_finalized_uninstantiated(); |
| 811 } | 764 } |
| 812 } | 765 } |
| 766 |
| 767 // Upper bounds of the finalized type arguments are only verified in checked |
| 768 // mode, since bound errors are never reported by the vm in production mode. |
| 769 if (FLAG_enable_type_checks && |
| 770 !full_arguments.IsNull() && |
| 771 full_arguments.IsInstantiated()) { |
| 772 ResolveAndFinalizeUpperBounds(type_class); |
| 773 Error& malformed_error = Error::Handle(); |
| 774 // Pass the full type argument vector as the bounds instantiator. |
| 775 if (!full_arguments.IsWithinBoundsOf(type_class, |
| 776 full_arguments, |
| 777 &malformed_error)) { |
| 778 ASSERT(!malformed_error.IsNull()); |
| 779 // The type argument vector of the type is not within bounds. The type |
| 780 // is malformed. Prepend malformed_error to new malformed type error in |
| 781 // order to report both locations. |
| 782 // Note that malformed bounds never result in a compile time error, even |
| 783 // in checked mode. Therefore, overwrite finalization with kFinalize |
| 784 // when finalizing the malformed type. |
| 785 FinalizeMalformedType( |
| 786 malformed_error, |
| 787 cls, parameterized_type, kFinalize, |
| 788 "type arguments of type '%s' are not within bounds", |
| 789 String::Handle(parameterized_type.Name()).ToCString()); |
| 790 return parameterized_type.raw(); |
| 791 } |
| 792 } |
| 793 |
| 794 // If the type class is a signature class, we also finalize its signature |
| 795 // type, thereby finalizing the result type and parameter types of its |
| 796 // signature function. |
| 797 // We do this after marking this type as finalized in order to allow a |
| 798 // function type to refer to itself via its parameter types and result type. |
| 799 if (type_class.IsSignatureClass()) { |
| 800 // Signature classes are finalized upon creation. |
| 801 ASSERT(type_class.is_finalized()); |
| 802 // Resolve and finalize the result and parameter types of the signature |
| 803 // function of this signature class. |
| 804 ResolveAndFinalizeSignature( |
| 805 type_class, Function::Handle(type_class.signature_function())); |
| 806 } |
| 807 |
| 813 return parameterized_type.Canonicalize(); | 808 return parameterized_type.Canonicalize(); |
| 814 } | 809 } |
| 815 | 810 |
| 816 | 811 |
| 817 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 812 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 818 const Function& function) { | 813 const Function& function) { |
| 819 // Resolve result type. | 814 // Resolve result type. |
| 820 AbstractType& type = AbstractType::Handle(function.result_type()); | 815 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 821 FinalizationKind result_finalization = kFinalize; | 816 FinalizationKind result_finalization = kFinalize; |
| 822 if (function.IsFactory()) { | 817 if (function.IsFactory()) { |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1414 void ClassFinalizer::ReportError(const char* format, ...) { | 1409 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1415 va_list args; | 1410 va_list args; |
| 1416 va_start(args, format); | 1411 va_start(args, format); |
| 1417 const Error& error = Error::Handle( | 1412 const Error& error = Error::Handle( |
| 1418 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1413 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1419 va_end(args); | 1414 va_end(args); |
| 1420 ReportError(error); | 1415 ReportError(error); |
| 1421 } | 1416 } |
| 1422 | 1417 |
| 1423 } // namespace dart | 1418 } // namespace dart |
| OLD | NEW |