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

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

Issue 21049012: Update VM to handle malformed types according to revised spec (issues 9055, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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 | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.h » ('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) 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/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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 ASSERT(factory.RedirectionTarget() == Function::null()); 340 ASSERT(factory.RedirectionTarget() == Function::null());
341 return; 341 return;
342 } 342 }
343 ASSERT(!type.IsTypeParameter()); // Resolved in parser. 343 ASSERT(!type.IsTypeParameter()); // Resolved in parser.
344 if (type.IsDynamicType()) { 344 if (type.IsDynamicType()) {
345 // Replace the type with a malformed type and compile a throw when called. 345 // Replace the type with a malformed type and compile a throw when called.
346 type = NewFinalizedMalformedType( 346 type = NewFinalizedMalformedType(
347 Error::Handle(), // No previous error. 347 Error::Handle(), // No previous error.
348 cls, 348 cls,
349 factory.token_pos(), 349 factory.token_pos(),
350 kResolveTypeParameters, // No compile-time error.
351 "factory may not redirect to 'dynamic'"); 350 "factory may not redirect to 'dynamic'");
352 factory.SetRedirectionType(type); 351 factory.SetRedirectionType(type);
353 ASSERT(factory.RedirectionTarget() == Function::null()); 352 ASSERT(factory.RedirectionTarget() == Function::null());
354 return; 353 return;
355 } 354 }
356 const Class& target_class = Class::Handle(type.type_class()); 355 const Class& target_class = Class::Handle(type.type_class());
357 String& target_class_name = String::Handle(target_class.Name()); 356 String& target_class_name = String::Handle(target_class.Name());
358 String& target_name = String::Handle( 357 String& target_name = String::Handle(
359 String::Concat(target_class_name, Symbols::Dot())); 358 String::Concat(target_class_name, Symbols::Dot()));
360 const String& identifier = String::Handle(factory.RedirectionIdentifier()); 359 const String& identifier = String::Handle(factory.RedirectionIdentifier());
361 if (!identifier.IsNull()) { 360 if (!identifier.IsNull()) {
362 target_name = String::Concat(target_name, identifier); 361 target_name = String::Concat(target_name, identifier);
363 } 362 }
364 363
365 // Verify that the target constructor of the redirection exists. 364 // Verify that the target constructor of the redirection exists.
366 target = target_class.LookupConstructor(target_name); 365 target = target_class.LookupConstructor(target_name);
367 if (target.IsNull()) { 366 if (target.IsNull()) {
368 target = target_class.LookupFactory(target_name); 367 target = target_class.LookupFactory(target_name);
369 } 368 }
370 if (target.IsNull()) { 369 if (target.IsNull()) {
371 const String& user_visible_target_name = 370 const String& user_visible_target_name =
372 identifier.IsNull() ? target_class_name : target_name; 371 identifier.IsNull() ? target_class_name : target_name;
373 // Replace the type with a malformed type and compile a throw when called. 372 // Replace the type with a malformed type and compile a throw when called.
374 type = NewFinalizedMalformedType( 373 type = NewFinalizedMalformedType(
375 Error::Handle(), // No previous error. 374 Error::Handle(), // No previous error.
376 cls, 375 cls,
377 factory.token_pos(), 376 factory.token_pos(),
378 kResolveTypeParameters, // No compile-time error.
379 "class '%s' has no constructor or factory named '%s'", 377 "class '%s' has no constructor or factory named '%s'",
380 target_class_name.ToCString(), 378 target_class_name.ToCString(),
381 user_visible_target_name.ToCString()); 379 user_visible_target_name.ToCString());
382 factory.SetRedirectionType(type); 380 factory.SetRedirectionType(type);
383 ASSERT(factory.RedirectionTarget() == Function::null()); 381 ASSERT(factory.RedirectionTarget() == Function::null());
384 return; 382 return;
385 } 383 }
386 384
387 // Verify that the target is compatible with the redirecting factory. 385 // Verify that the target is compatible with the redirecting factory.
388 if (!target.HasCompatibleParametersWith(factory)) { 386 if (!target.HasCompatibleParametersWith(factory)) {
389 type = NewFinalizedMalformedType( 387 type = NewFinalizedMalformedType(
390 Error::Handle(), // No previous error. 388 Error::Handle(), // No previous error.
391 cls, 389 cls,
392 factory.token_pos(), 390 factory.token_pos(),
393 kResolveTypeParameters, // No compile-time error.
394 "constructor '%s' has incompatible parameters with " 391 "constructor '%s' has incompatible parameters with "
395 "redirecting factory '%s'", 392 "redirecting factory '%s'",
396 String::Handle(target.name()).ToCString(), 393 String::Handle(target.name()).ToCString(),
397 String::Handle(factory.name()).ToCString()); 394 String::Handle(factory.name()).ToCString());
398 factory.SetRedirectionType(type); 395 factory.SetRedirectionType(type);
399 ASSERT(factory.RedirectionTarget() == Function::null()); 396 ASSERT(factory.RedirectionTarget() == Function::null());
400 return; 397 return;
401 } 398 }
402 399
403 // Verify that the target is const if the redirecting factory is const. 400 // Verify that the target is const if the redirecting factory is const.
(...skipping 26 matching lines...) Expand all
430 // If the target type refers to type parameters, substitute them with the 427 // If the target type refers to type parameters, substitute them with the
431 // type arguments of the redirection type. 428 // type arguments of the redirection type.
432 if (!target_type.IsInstantiated()) { 429 if (!target_type.IsInstantiated()) {
433 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( 430 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(
434 type.arguments()); 431 type.arguments());
435 Error& malformed_error = Error::Handle(); 432 Error& malformed_error = Error::Handle();
436 target_type ^= target_type.InstantiateFrom(type_args, &malformed_error); 433 target_type ^= target_type.InstantiateFrom(type_args, &malformed_error);
437 if (malformed_error.IsNull()) { 434 if (malformed_error.IsNull()) {
438 target_type ^= FinalizeType(cls, target_type, kCanonicalize); 435 target_type ^= FinalizeType(cls, target_type, kCanonicalize);
439 } else { 436 } else {
440 FinalizeMalformedType(malformed_error, 437 FinalizeMalformedType(malformed_error, cls, target_type,
441 cls, target_type, kFinalize,
442 "cannot resolve redirecting factory"); 438 "cannot resolve redirecting factory");
443 target_target = Function::null(); 439 target_target = Function::null();
444 } 440 }
445 } 441 }
446 } 442 }
447 factory.SetRedirectionType(target_type); 443 factory.SetRedirectionType(target_type);
448 factory.SetRedirectionTarget(target_target); 444 factory.SetRedirectionTarget(target_target);
449 } 445 }
450 446
451 447
452 void ClassFinalizer::ResolveType(const Class& cls, 448 void ClassFinalizer::ResolveType(const Class& cls,
453 const AbstractType& type, 449 const AbstractType& type,
454 FinalizationKind finalization) { 450 FinalizationKind finalization) {
455 if (type.IsResolved() || type.IsFinalized()) { 451 if (type.IsResolved() || type.IsFinalized()) {
456 if ((finalization == kCanonicalizeWellFormed) && type.IsMalformed()) {
457 ReportError(Error::Handle(type.malformed_error()));
458 }
459 return; 452 return;
460 } 453 }
461 if (FLAG_trace_type_finalization) { 454 if (FLAG_trace_type_finalization) {
462 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); 455 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString());
463 } 456 }
464 457
465 // Resolve the type class. 458 // Resolve the type class.
466 if (!type.HasResolvedTypeClass()) { 459 if (!type.HasResolvedTypeClass()) {
467 // Type parameters are always resolved in the parser in the correct 460 // Type parameters are always resolved in the parser in the correct
468 // non-static scope or factory scope. That resolution scope is unknown here. 461 // non-static scope or factory scope. That resolution scope is unknown here.
469 // Being able to resolve a type parameter from class cls here would indicate 462 // Being able to resolve a type parameter from class cls here would indicate
470 // that the type parameter appeared in a static scope. Leaving the type as 463 // that the type parameter appeared in a static scope. Leaving the type as
471 // unresolved is the correct thing to do. 464 // unresolved is the correct thing to do.
472 465
473 // Lookup the type class. 466 // Lookup the type class.
474 const UnresolvedClass& unresolved_class = 467 const UnresolvedClass& unresolved_class =
475 UnresolvedClass::Handle(type.unresolved_class()); 468 UnresolvedClass::Handle(type.unresolved_class());
476 Error& ambiguous_error = Error::Handle(); 469 Error& ambiguous_error = Error::Handle();
477 const Class& type_class = 470 const Class& type_class =
478 Class::Handle(ResolveClass(cls, unresolved_class, &ambiguous_error)); 471 Class::Handle(ResolveClass(cls, unresolved_class, &ambiguous_error));
479 472
480 // Replace unresolved class with resolved type class. 473 // Replace unresolved class with resolved type class.
481 const Type& parameterized_type = Type::Cast(type); 474 const Type& parameterized_type = Type::Cast(type);
482 if (!type_class.IsNull()) { 475 if (type_class.IsNull()) {
483 parameterized_type.set_type_class(type_class); 476 if ((finalization == kCanonicalizeWellFormed) ||
484 } else { 477 FLAG_error_on_malformed_type) {
485 // The type class could not be resolved. The type is malformed. 478 // The type class could not be resolved. The type is malformed.
486 FinalizeMalformedType(ambiguous_error, // May be null. 479 FinalizeMalformedType(
487 cls, parameterized_type, finalization, 480 ambiguous_error, // May be null.
488 "cannot resolve class name '%s' from '%s'", 481 cls,
489 String::Handle(unresolved_class.Name()).ToCString(), 482 parameterized_type,
490 String::Handle(cls.Name()).ToCString()); 483 "cannot resolve class '%s' from '%s'",
484 String::Handle(unresolved_class.Name()).ToCString(),
485 String::Handle(cls.Name()).ToCString());
486 } else {
487 // Map the malformed type to dynamic and ignore type arguments.
488 parameterized_type.set_type_class(Class::Handle(
489 Object::dynamic_class()));
490 parameterized_type.set_arguments(
491 Object::null_abstract_type_arguments());
492 }
491 return; 493 return;
492 } 494 }
495 parameterized_type.set_type_class(type_class);
493 } 496 }
494 497
495 // Resolve type arguments, if any. 498 // Resolve type arguments, if any.
496 const AbstractTypeArguments& arguments = 499 const AbstractTypeArguments& arguments =
497 AbstractTypeArguments::Handle(type.arguments()); 500 AbstractTypeArguments::Handle(type.arguments());
498 if (!arguments.IsNull()) { 501 if (!arguments.IsNull()) {
499 intptr_t num_arguments = arguments.Length(); 502 intptr_t num_arguments = arguments.Length();
500 AbstractType& type_argument = AbstractType::Handle(); 503 AbstractType& type_argument = AbstractType::Handle();
501 for (intptr_t i = 0; i < num_arguments; i++) { 504 for (intptr_t i = 0; i < num_arguments; i++) {
502 type_argument = arguments.TypeAt(i); 505 type_argument = arguments.TypeAt(i);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 } 704 }
702 } 705 }
703 706
704 707
705 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, 708 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
706 const AbstractType& type, 709 const AbstractType& type,
707 FinalizationKind finalization) { 710 FinalizationKind finalization) {
708 if (type.IsFinalized()) { 711 if (type.IsFinalized()) {
709 // Ensure type is canonical if canonicalization is requested, unless type is 712 // Ensure type is canonical if canonicalization is requested, unless type is
710 // malformed. 713 // malformed.
711 if (finalization >= kCanonicalize) { 714 if ((finalization >= kCanonicalize) && !type.IsMalformed()) {
712 if (type.IsMalformed()) { 715 return type.Canonicalize();
713 if (finalization == kCanonicalizeWellFormed) {
714 ReportError(Error::Handle(type.malformed_error()));
715 }
716 } else {
717 return type.Canonicalize();
718 }
719 } 716 }
720 return type.raw(); 717 return type.raw();
721 } 718 }
722 ASSERT(type.IsResolved()); 719 ASSERT(type.IsResolved());
723 ASSERT(finalization >= kFinalize); 720 ASSERT(finalization >= kFinalize);
724 721
725 if (FLAG_trace_type_finalization) { 722 if (FLAG_trace_type_finalization) {
726 OS::Print("Finalize type '%s' for class '%s'\n", 723 OS::Print("Finalize type '%s' for class '%s'\n",
727 String::Handle(type.Name()).ToCString(), 724 String::Handle(type.Name()).ToCString(),
728 cls.ToCString()); 725 cls.ToCString());
(...skipping 13 matching lines...) Expand all
742 parameterized_class.NumTypeParameters(); 739 parameterized_class.NumTypeParameters();
743 type_parameter.set_index(type_parameter.index() + offset); 740 type_parameter.set_index(type_parameter.index() + offset);
744 type_parameter.set_is_finalized(); 741 type_parameter.set_is_finalized();
745 // We do not canonicalize type parameters. 742 // We do not canonicalize type parameters.
746 return type_parameter.raw(); 743 return type_parameter.raw();
747 } 744 }
748 745
749 // At this point, we can only have a parameterized_type. 746 // At this point, we can only have a parameterized_type.
750 const Type& parameterized_type = Type::Cast(type); 747 const Type& parameterized_type = Type::Cast(type);
751 748
752 if (parameterized_type.IsBeingFinalized()) { 749 // Types illegally referring to themselves should have been detected earlier.
753 // Self reference detected. The type is malformed. 750 ASSERT(!parameterized_type.IsBeingFinalized());
754 FinalizeMalformedType(
755 Error::Handle(), // No previous error.
756 cls, parameterized_type, finalization,
757 "type '%s' illegally refers to itself",
758 String::Handle(parameterized_type.UserVisibleName()).ToCString());
759 return parameterized_type.raw();
760 }
761 751
762 // Mark type as being finalized in order to detect illegal self reference. 752 // Mark type as being finalized in order to detect illegal self reference.
763 parameterized_type.set_is_being_finalized(); 753 parameterized_type.set_is_being_finalized();
764 754
765 // The type class does not need to be finalized in order to finalize the type, 755 // The type class does not need to be finalized in order to finalize the type,
766 // however, it must at least be resolved (this was done as part of resolving 756 // however, it must at least be resolved (this was done as part of resolving
767 // the type itself, a precondition to calling FinalizeType). 757 // the type itself, a precondition to calling FinalizeType).
768 // Also, the interfaces of the type class must be resolved and the type 758 // Also, the interfaces of the type class must be resolved and the type
769 // parameters of the type class must be finalized. 759 // parameters of the type class must be finalized.
770 Class& type_class = Class::Handle(parameterized_type.type_class()); 760 Class& type_class = Class::Handle(parameterized_type.type_class());
771 if (!type_class.is_type_finalized()) { 761 if (!type_class.is_type_finalized()) {
772 FinalizeTypeParameters(type_class); 762 FinalizeTypeParameters(type_class);
773 ResolveUpperBounds(type_class); 763 ResolveUpperBounds(type_class);
774 } 764 }
775 765
776 // Finalize the current type arguments of the type, which are still the 766 // Finalize the current type arguments of the type, which are still the
777 // parsed type arguments. 767 // parsed type arguments.
778 AbstractTypeArguments& arguments = 768 AbstractTypeArguments& arguments =
779 AbstractTypeArguments::Handle(parameterized_type.arguments()); 769 AbstractTypeArguments::Handle(parameterized_type.arguments());
780 if (!arguments.IsNull()) { 770 if (!arguments.IsNull()) {
781 intptr_t num_arguments = arguments.Length(); 771 intptr_t num_arguments = arguments.Length();
782 AbstractType& type_argument = AbstractType::Handle(); 772 AbstractType& type_argument = AbstractType::Handle();
783 for (intptr_t i = 0; i < num_arguments; i++) { 773 for (intptr_t i = 0; i < num_arguments; i++) {
784 type_argument = arguments.TypeAt(i); 774 type_argument = arguments.TypeAt(i);
785 type_argument = FinalizeType(cls, type_argument, finalization); 775 type_argument = FinalizeType(cls, type_argument, finalization);
786 if (type_argument.IsMalformed()) { 776 if (type_argument.IsMalformed()) {
787 // In production mode, malformed type arguments are mapped to dynamic. 777 // Malformed type arguments are mapped to dynamic.
788 // In checked mode, a type with malformed type arguments is malformed. 778 type_argument = Type::DynamicType();
789 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
790 const Error& error = Error::Handle(type_argument.malformed_error());
791 const String& type_name =
792 String::Handle(parameterized_type.UserVisibleName());
793 FinalizeMalformedType(error, cls, parameterized_type, finalization,
794 "type '%s' has malformed type argument",
795 type_name.ToCString());
796 return parameterized_type.raw();
797 } else {
798 type_argument = Type::DynamicType();
799 }
800 } 779 }
801 arguments.SetTypeAt(i, type_argument); 780 arguments.SetTypeAt(i, type_argument);
802 } 781 }
803 } 782 }
804 783
805 // The finalized type argument vector needs num_type_arguments types. 784 // The finalized type argument vector needs num_type_arguments types.
806 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 785 const intptr_t num_type_arguments = type_class.NumTypeArguments();
807 // The type class has num_type_parameters type parameters. 786 // The type class has num_type_parameters type parameters.
808 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 787 const intptr_t num_type_parameters = type_class.NumTypeParameters();
809 788
810 // Initialize the type argument vector. 789 // Initialize the type argument vector.
811 // Check the number of parsed type arguments, if any. 790 // Check the number of parsed type arguments, if any.
812 // Specifying no type arguments indicates a raw type, which is not an error. 791 // Specifying no type arguments indicates a raw type, which is not an error.
813 // However, type parameter bounds are checked below, even for a raw type. 792 // However, type parameter bounds are checked below, even for a raw type.
814 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 793 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
815 // Wrong number of type arguments. The type is malformed. 794 // Wrong number of type arguments. The type is malformed.
816 if (finalization >= kCanonicalizeExpression) { 795 if (FLAG_error_on_malformed_type) {
817 const Script& script = Script::Handle(cls.script()); 796 const Script& script = Script::Handle(cls.script());
818 const String& type_name = 797 const String& type_class_name = String::Handle(type_class.Name());
819 String::Handle(parameterized_type.UserVisibleName());
820 ReportError(script, parameterized_type.token_pos(), 798 ReportError(script, parameterized_type.token_pos(),
821 "wrong number of type arguments in type '%s'", 799 "wrong number of type arguments for class '%s'",
822 type_name.ToCString()); 800 type_class_name.ToCString());
823 } 801 }
824 FinalizeMalformedType( 802 // Make the type raw and continue without reporting any error.
825 Error::Handle(), // No previous error. 803 // A static warning should have been reported.
826 cls, parameterized_type, finalization, 804 arguments = AbstractTypeArguments::null();
827 "wrong number of type arguments in type '%s'", 805 parameterized_type.set_arguments(arguments);
828 String::Handle(parameterized_type.UserVisibleName()).ToCString());
829 return parameterized_type.raw();
830 } 806 }
831 // The full type argument vector consists of the type arguments of the 807 // The full type argument vector consists of the type arguments of the
832 // super types of type_class, which may be initialized from the parsed 808 // super types of type_class, which may be initialized from the parsed
833 // type arguments, followed by the parsed type arguments. 809 // type arguments, followed by the parsed type arguments.
834 TypeArguments& full_arguments = TypeArguments::Handle(); 810 TypeArguments& full_arguments = TypeArguments::Handle();
835 Error& bound_error = Error::Handle(); 811 Error& bound_error = Error::Handle();
836 if (num_type_arguments > 0) { 812 if (num_type_arguments > 0) {
837 // If no type arguments were parsed and if the super types do not prepend 813 // If no type arguments were parsed and if the super types do not prepend
838 // type arguments to the vector, we can leave the vector as null. 814 // type arguments to the vector, we can leave the vector as null.
839 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { 815 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 if (type_class.IsSignatureClass()) { 877 if (type_class.IsSignatureClass()) {
902 // The class may be created while parsing a function body, after all 878 // The class may be created while parsing a function body, after all
903 // pending classes have already been finalized. 879 // pending classes have already been finalized.
904 FinalizeTypesInClass(type_class); 880 FinalizeTypesInClass(type_class);
905 } 881 }
906 882
907 // If a bound error occurred, return a BoundedType with a malformed bound. 883 // If a bound error occurred, return a BoundedType with a malformed bound.
908 // The malformed bound will be ignored in production mode. 884 // The malformed bound will be ignored in production mode.
909 if (!bound_error.IsNull()) { 885 if (!bound_error.IsNull()) {
910 // No compile-time error during finalization. 886 // No compile-time error during finalization.
911 FinalizationKind bound_finalization = kResolveTypeParameters;
912 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
913 bound_finalization = finalization;
914 }
915 const String& parameterized_type_name = String::Handle( 887 const String& parameterized_type_name = String::Handle(
916 parameterized_type.UserVisibleName()); 888 parameterized_type.UserVisibleName());
917 const Type& malformed_bound = Type::Handle( 889 const Type& malformed_bound = Type::Handle(
918 NewFinalizedMalformedType(bound_error, 890 NewFinalizedMalformedType(bound_error,
919 cls, 891 cls,
920 parameterized_type.token_pos(), 892 parameterized_type.token_pos(),
921 bound_finalization,
922 "type '%s' has an out of bound type argument", 893 "type '%s' has an out of bound type argument",
923 parameterized_type_name.ToCString())); 894 parameterized_type_name.ToCString()));
924 return BoundedType::New(parameterized_type, 895 return BoundedType::New(parameterized_type,
925 malformed_bound, 896 malformed_bound,
926 TypeParameter::Handle()); 897 TypeParameter::Handle());
927 } 898 }
928 899
929 if (finalization >= kCanonicalize) { 900 if (finalization >= kCanonicalize) {
930 return parameterized_type.Canonicalize(); 901 return parameterized_type.Canonicalize();
931 } else { 902 } else {
932 return parameterized_type.raw(); 903 return parameterized_type.raw();
933 } 904 }
934 } 905 }
935 906
936 907
937 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 908 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
938 const Function& function) { 909 const Function& function) {
939 // Resolve result type. 910 // Resolve result type.
940 AbstractType& type = AbstractType::Handle(function.result_type()); 911 AbstractType& type = AbstractType::Handle(function.result_type());
941 // It is not a compile time error if this name does not resolve to a class or 912 // It is not a compile time error if this name does not resolve to a class or
942 // interface. 913 // interface.
943 ResolveType(cls, type, kCanonicalize); 914 ResolveType(cls, type, kCanonicalize);
944 type = FinalizeType(cls, type, kCanonicalize); 915 type = FinalizeType(cls, type, kCanonicalize);
945 // In production mode, a malformed result type is mapped to dynamic. 916 // A malformed result type is mapped to dynamic.
946 if (!FLAG_enable_type_checks && type.IsMalformed()) { 917 ASSERT(!type.IsMalformed());
947 type = Type::DynamicType();
948 }
949 function.set_result_type(type); 918 function.set_result_type(type);
950 // Resolve formal parameter types. 919 // Resolve formal parameter types.
951 const intptr_t num_parameters = function.NumParameters(); 920 const intptr_t num_parameters = function.NumParameters();
952 for (intptr_t i = 0; i < num_parameters; i++) { 921 for (intptr_t i = 0; i < num_parameters; i++) {
953 type = function.ParameterTypeAt(i); 922 type = function.ParameterTypeAt(i);
954 ResolveType(cls, type, kCanonicalize); 923 ResolveType(cls, type, kCanonicalize);
955 type = FinalizeType(cls, type, kCanonicalize); 924 type = FinalizeType(cls, type, kCanonicalize);
956 // In production mode, a malformed parameter type is mapped to dynamic. 925 // A malformed parameter type is mapped to dynamic.
957 if (!FLAG_enable_type_checks && type.IsMalformed()) { 926 ASSERT(!type.IsMalformed());
958 type = Type::DynamicType();
959 }
960 function.SetParameterTypeAt(i, type); 927 function.SetParameterTypeAt(i, type);
961 } 928 }
962 } 929 }
963 930
964 931
965 // Check if an instance field or method of same name exists 932 // Check if an instance field or method of same name exists
966 // in any super class. 933 // in any super class.
967 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, 934 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls,
968 const String& name) { 935 const String& name) {
969 Class& super_class = Class::Handle(); 936 Class& super_class = Class::Handle();
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 // are lifted. 1835 // are lifted.
1869 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); 1836 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary();
1870 1837
1871 // Resolve and check the super type and interfaces of cls. 1838 // Resolve and check the super type and interfaces of cls.
1872 visited->Add(cls_index); 1839 visited->Add(cls_index);
1873 AbstractType& interface = AbstractType::Handle(); 1840 AbstractType& interface = AbstractType::Handle();
1874 Class& interface_class = Class::Handle(); 1841 Class& interface_class = Class::Handle();
1875 1842
1876 // Resolve super type. Failures lead to a longjmp. 1843 // Resolve super type. Failures lead to a longjmp.
1877 ResolveType(cls, super_type, kCanonicalizeWellFormed); 1844 ResolveType(cls, super_type, kCanonicalizeWellFormed);
1845 if (super_type.IsMalformed()) {
1846 ReportError(Error::Handle(super_type.malformed_error()));
1847 }
1878 if (super_type.IsDynamicType()) { 1848 if (super_type.IsDynamicType()) {
1879 const Script& script = Script::Handle(cls.script()); 1849 const Script& script = Script::Handle(cls.script());
1880 ReportError(script, cls.token_pos(), 1850 ReportError(script, cls.token_pos(),
1881 "class '%s' may not extend 'dynamic'", 1851 "class '%s' may not extend 'dynamic'",
1882 String::Handle(cls.Name()).ToCString()); 1852 String::Handle(cls.Name()).ToCString());
1883 } 1853 }
1884 1854
1885 interface_class = super_type.type_class(); 1855 interface_class = super_type.type_class();
1886 // If cls belongs to core lib or to core lib's implementation, restrictions 1856 // If cls belongs to core lib or to core lib's implementation, restrictions
1887 // about allowed interfaces are lifted. 1857 // about allowed interfaces are lifted.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 } 1903 }
1934 } 1904 }
1935 // Now resolve the super interfaces of the super type. 1905 // Now resolve the super interfaces of the super type.
1936 ResolveSuperTypeAndInterfaces(interface_class, visited); 1906 ResolveSuperTypeAndInterfaces(interface_class, visited);
1937 1907
1938 // Resolve interfaces. Failures lead to a longjmp. 1908 // Resolve interfaces. Failures lead to a longjmp.
1939 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { 1909 for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
1940 interface ^= super_interfaces.At(i); 1910 interface ^= super_interfaces.At(i);
1941 ResolveType(cls, interface, kCanonicalizeWellFormed); 1911 ResolveType(cls, interface, kCanonicalizeWellFormed);
1942 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. 1912 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser.
1913 if (interface.IsMalformed()) {
1914 ReportError(Error::Handle(interface.malformed_error()));
1915 }
1943 if (interface.IsDynamicType()) { 1916 if (interface.IsDynamicType()) {
1944 const Script& script = Script::Handle(cls.script()); 1917 const Script& script = Script::Handle(cls.script());
1945 ReportError(script, cls.token_pos(), 1918 ReportError(script, cls.token_pos(),
1946 "'dynamic' may not be used as interface"); 1919 "'dynamic' may not be used as interface");
1947 } 1920 }
1948 interface_class = interface.type_class(); 1921 interface_class = interface.type_class();
1949 if (interface_class.IsSignatureClass()) { 1922 if (interface_class.IsSignatureClass()) {
1950 const Script& script = Script::Handle(cls.script()); 1923 const Script& script = Script::Handle(cls.script());
1951 ReportError(script, cls.token_pos(), 1924 ReportError(script, cls.token_pos(),
1952 "'%s' is used where an interface or class name is expected", 1925 "'%s' is used where an interface or class name is expected",
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2044 for (intptr_t i = 0; i < len; i++) { 2017 for (intptr_t i = 0; i < len; i++) {
2045 field ^= fields_array.At(i); 2018 field ^= fields_array.At(i);
2046 OS::Print(" %s\n", field.ToCString()); 2019 OS::Print(" %s\n", field.ToCString());
2047 } 2020 }
2048 } 2021 }
2049 2022
2050 // Either report an error or mark the type as malformed. 2023 // Either report an error or mark the type as malformed.
2051 void ClassFinalizer::ReportMalformedType(const Error& prev_error, 2024 void ClassFinalizer::ReportMalformedType(const Error& prev_error,
2052 const Class& cls, 2025 const Class& cls,
2053 const Type& type, 2026 const Type& type,
2054 FinalizationKind finalization,
2055 const char* format, 2027 const char* format,
2056 va_list args) { 2028 va_list args) {
2057 LanguageError& error = LanguageError::Handle(); 2029 LanguageError& error = LanguageError::Handle();
2058 if (FLAG_enable_type_checks || 2030 const Script& script = Script::Handle(cls.script());
2059 !type.HasResolvedTypeClass() || 2031 if (prev_error.IsNull()) {
2060 (finalization == kCanonicalizeWellFormed) || 2032 error ^= Parser::FormatError(
2061 FLAG_error_on_malformed_type) { 2033 script, type.token_pos(), "Error", format, args);
2062 const Script& script = Script::Handle(cls.script()); 2034 } else {
2063 if (prev_error.IsNull()) { 2035 error ^= Parser::FormatErrorWithAppend(
2064 error ^= Parser::FormatError( 2036 prev_error, script, type.token_pos(), "Error", format, args);
2065 script, type.token_pos(), "Error", format, args);
2066 } else {
2067 error ^= Parser::FormatErrorWithAppend(
2068 prev_error, script, type.token_pos(), "Error", format, args);
2069 }
2070 if ((finalization == kCanonicalizeWellFormed) ||
2071 FLAG_error_on_malformed_type) {
2072 ReportError(error);
2073 }
2074 } 2037 }
2075 // In checked mode, always mark the type as malformed. 2038 if (FLAG_error_on_malformed_type) {
2076 // In production mode, mark the type as malformed only if its type class is 2039 ReportError(error);
2077 // not resolved. 2040 }
2078 // In both mode, make the type raw, since it may not be possible to 2041 type.set_malformed_error(error);
2042 // Make the type raw, since it may not be possible to
2079 // properly finalize its type arguments. 2043 // properly finalize its type arguments.
2080 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { 2044 type.set_type_class(Class::Handle(Object::dynamic_class()));
2081 type.set_malformed_error(error);
2082 }
2083 type.set_arguments(Object::null_abstract_type_arguments()); 2045 type.set_arguments(Object::null_abstract_type_arguments());
2084 if (!type.IsFinalized()) { 2046 if (!type.IsFinalized()) {
2085 type.SetIsFinalized(); 2047 type.SetIsFinalized();
2086 // Do not canonicalize malformed types, since they may not be resolved. 2048 // Do not canonicalize malformed types, since they may not be resolved.
2087 } else { 2049 } else {
2088 // The only case where the malformed type was already finalized is when its 2050 // The only case where the malformed type was already finalized is when its
2089 // type arguments are not within bounds. In that case, we have a prev_error. 2051 // type arguments are not within bounds. In that case, we have a prev_error.
2090 ASSERT(!prev_error.IsNull()); 2052 ASSERT(!prev_error.IsNull());
2091 } 2053 }
2092 } 2054 }
2093 2055
2094 2056
2095 RawType* ClassFinalizer::NewFinalizedMalformedType( 2057 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error,
2096 const Error& prev_error, 2058 const Class& cls,
2097 const Class& cls, 2059 intptr_t type_pos,
2098 intptr_t type_pos, 2060 const char* format, ...) {
2099 FinalizationKind finalization,
2100 const char* format, ...) {
2101 va_list args; 2061 va_list args;
2102 va_start(args, format); 2062 va_start(args, format);
2103 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( 2063 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle(
2104 UnresolvedClass::New(LibraryPrefix::Handle(), 2064 UnresolvedClass::New(LibraryPrefix::Handle(),
2105 Symbols::Empty(), 2065 Symbols::Empty(),
2106 type_pos)); 2066 type_pos));
2107 const Type& type = Type::Handle( 2067 const Type& type = Type::Handle(
2108 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); 2068 Type::New(unresolved_class, TypeArguments::Handle(), type_pos));
2109 ReportMalformedType(prev_error, cls, type, finalization, format, args); 2069 ReportMalformedType(prev_error, cls, type, format, args);
2110 va_end(args); 2070 va_end(args);
2111 ASSERT(type.IsMalformed()); 2071 ASSERT(type.IsMalformed());
2112 ASSERT(type.IsFinalized()); 2072 ASSERT(type.IsFinalized());
2113 return type.raw(); 2073 return type.raw();
2114 } 2074 }
2115 2075
2116 2076
2117 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, 2077 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
2118 const Class& cls, 2078 const Class& cls,
2119 const Type& type, 2079 const Type& type,
2120 FinalizationKind finalization,
2121 const char* format, ...) { 2080 const char* format, ...) {
2122 va_list args; 2081 va_list args;
2123 va_start(args, format); 2082 va_start(args, format);
2124 ReportMalformedType(prev_error, cls, type, finalization, format, args); 2083 ReportMalformedType(prev_error, cls, type, format, args);
2125 va_end(args); 2084 va_end(args);
2126 } 2085 }
2127 2086
2128 2087
2129 void ClassFinalizer::ReportError(const Error& error) { 2088 void ClassFinalizer::ReportError(const Error& error) {
2130 Isolate::Current()->long_jump_base()->Jump(1, error); 2089 Isolate::Current()->long_jump_base()->Jump(1, error);
2131 UNREACHABLE(); 2090 UNREACHABLE();
2132 } 2091 }
2133 2092
2134 2093
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 expected_name ^= String::New("_offset"); 2166 expected_name ^= String::New("_offset");
2208 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2167 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2209 field ^= fields_array.At(2); 2168 field ^= fields_array.At(2);
2210 ASSERT(field.Offset() == TypedDataView::length_offset()); 2169 ASSERT(field.Offset() == TypedDataView::length_offset());
2211 name ^= field.name(); 2170 name ^= field.name();
2212 ASSERT(name.Equals("length")); 2171 ASSERT(name.Equals("length"));
2213 #endif 2172 #endif
2214 } 2173 }
2215 2174
2216 } // namespace dart 2175 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698