Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 10388019: Allow self referencing typedefs (issue 2490). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698