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

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

Issue 154393003: Implement eager instantiation and canonicalization of type arguments at run (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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
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/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 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 // of the redirection chain. 395 // of the redirection chain.
396 ResolveRedirectingFactoryTarget(target_class, target, visited_factories); 396 ResolveRedirectingFactoryTarget(target_class, target, visited_factories);
397 Type& target_type = Type::Handle(target.RedirectionType()); 397 Type& target_type = Type::Handle(target.RedirectionType());
398 Function& target_target = Function::Handle(target.RedirectionTarget()); 398 Function& target_target = Function::Handle(target.RedirectionTarget());
399 if (target_target.IsNull()) { 399 if (target_target.IsNull()) {
400 ASSERT(target_type.IsMalformed()); 400 ASSERT(target_type.IsMalformed());
401 } else { 401 } else {
402 // If the target type refers to type parameters, substitute them with the 402 // If the target type refers to type parameters, substitute them with the
403 // type arguments of the redirection type. 403 // type arguments of the redirection type.
404 if (!target_type.IsInstantiated()) { 404 if (!target_type.IsInstantiated()) {
405 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( 405 const TypeArguments& type_args = TypeArguments::Handle(type.arguments());
406 type.arguments());
407 Error& bound_error = Error::Handle(); 406 Error& bound_error = Error::Handle();
408 target_type ^= target_type.InstantiateFrom(type_args, &bound_error); 407 target_type ^= target_type.InstantiateFrom(type_args, &bound_error);
409 if (bound_error.IsNull()) { 408 if (bound_error.IsNull()) {
410 target_type ^= FinalizeType(cls, target_type, kCanonicalize); 409 target_type ^= FinalizeType(cls, target_type, kCanonicalize);
411 } else { 410 } else {
412 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); 411 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated());
413 const Script& script = Script::Handle(target_class.script()); 412 const Script& script = Script::Handle(target_class.script());
414 FinalizeMalformedType(bound_error, script, target_type, 413 FinalizeMalformedType(bound_error, script, target_type,
415 "cannot resolve redirecting factory"); 414 "cannot resolve redirecting factory");
416 target_target = Function::null(); 415 target_target = Function::null();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 parameterized_type, 453 parameterized_type,
455 "cannot resolve class '%s' from '%s'", 454 "cannot resolve class '%s' from '%s'",
456 String::Handle(unresolved_class.Name()).ToCString(), 455 String::Handle(unresolved_class.Name()).ToCString(),
457 String::Handle(cls.Name()).ToCString()); 456 String::Handle(cls.Name()).ToCString());
458 return; 457 return;
459 } 458 }
460 parameterized_type.set_type_class(type_class); 459 parameterized_type.set_type_class(type_class);
461 } 460 }
462 461
463 // Resolve type arguments, if any. 462 // Resolve type arguments, if any.
464 const AbstractTypeArguments& arguments = 463 const TypeArguments& arguments = TypeArguments::Handle(type.arguments());
465 AbstractTypeArguments::Handle(type.arguments());
466 if (!arguments.IsNull()) { 464 if (!arguments.IsNull()) {
467 const intptr_t num_arguments = arguments.Length(); 465 const intptr_t num_arguments = arguments.Length();
468 AbstractType& type_argument = AbstractType::Handle(); 466 AbstractType& type_argument = AbstractType::Handle();
469 for (intptr_t i = 0; i < num_arguments; i++) { 467 for (intptr_t i = 0; i < num_arguments; i++) {
470 type_argument = arguments.TypeAt(i); 468 type_argument = arguments.TypeAt(i);
471 ResolveType(cls, type_argument); 469 ResolveType(cls, type_argument);
472 } 470 }
473 } 471 }
474 } 472 }
475 473
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 // cls = C, arguments = [dynamic, String, double], 522 // cls = C, arguments = [dynamic, String, double],
525 // num_uninitialized_arguments = 1, 523 // num_uninitialized_arguments = 1,
526 // i.e. cls_args = [String, double], offset = 1, length = 2. 524 // i.e. cls_args = [String, double], offset = 1, length = 2.
527 // Output: arguments = [int, String, double] 525 // Output: arguments = [int, String, double]
528 // 526 //
529 // It is too early to canonicalize the type arguments of the vector, because 527 // It is too early to canonicalize the type arguments of the vector, because
530 // several type argument vectors may be mutually recursive and finalized at the 528 // several type argument vectors may be mutually recursive and finalized at the
531 // same time. Canonicalization happens when pending types are processed. 529 // same time. Canonicalization happens when pending types are processed.
532 void ClassFinalizer::FinalizeTypeArguments( 530 void ClassFinalizer::FinalizeTypeArguments(
533 const Class& cls, 531 const Class& cls,
534 const AbstractTypeArguments& arguments, 532 const TypeArguments& arguments,
535 intptr_t num_uninitialized_arguments, 533 intptr_t num_uninitialized_arguments,
536 Error* bound_error, 534 Error* bound_error,
537 GrowableObjectArray* pending_types) { 535 GrowableObjectArray* pending_types) {
538 ASSERT(arguments.Length() >= cls.NumTypeArguments()); 536 ASSERT(arguments.Length() >= cls.NumTypeArguments());
539 if (!cls.is_type_finalized()) { 537 if (!cls.is_type_finalized()) {
540 FinalizeTypeParameters(cls, pending_types); 538 FinalizeTypeParameters(cls, pending_types);
541 ResolveUpperBounds(cls); 539 ResolveUpperBounds(cls);
542 } 540 }
543 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 541 AbstractType& super_type = AbstractType::Handle(cls.super_type());
544 if (!super_type.IsNull()) { 542 if (!super_type.IsNull()) {
545 const Class& super_class = Class::Handle(super_type.type_class()); 543 const Class& super_class = Class::Handle(super_type.type_class());
546 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 544 const intptr_t num_super_type_params = super_class.NumTypeParameters();
547 const intptr_t num_super_type_args = super_class.NumTypeArguments(); 545 const intptr_t num_super_type_args = super_class.NumTypeArguments();
548 ASSERT(num_super_type_args == 546 ASSERT(num_super_type_args ==
549 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); 547 (cls.NumTypeArguments() - cls.NumOwnTypeArguments()));
550 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { 548 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) {
551 super_type ^= FinalizeType( 549 super_type ^= FinalizeType(
552 cls, super_type, kFinalize, pending_types); 550 cls, super_type, kFinalize, pending_types);
553 cls.set_super_type(super_type); 551 cls.set_super_type(super_type);
554 } 552 }
555 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle( 553 TypeArguments& super_type_args = TypeArguments::Handle(
556 super_type.arguments()); 554 super_type.arguments());
557 // Offset of super type's type parameters in cls' type argument vector. 555 // Offset of super type's type parameters in cls' type argument vector.
558 const intptr_t super_offset = num_super_type_args - num_super_type_params; 556 const intptr_t super_offset = num_super_type_args - num_super_type_params;
559 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); 557 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType());
560 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { 558 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) {
561 if (!super_type_args.IsNull()) { 559 if (!super_type_args.IsNull()) {
562 super_type_arg = super_type_args.TypeAt(i); 560 super_type_arg = super_type_args.TypeAt(i);
563 if (!super_type_arg.IsFinalized()) { 561 if (!super_type_arg.IsFinalized()) {
564 super_type_arg ^= FinalizeType( 562 super_type_arg ^= FinalizeType(
565 cls, super_type_arg, kFinalize, pending_types); 563 cls, super_type_arg, kFinalize, pending_types);
(...skipping 21 matching lines...) Expand all
587 bound_error, pending_types); 585 bound_error, pending_types);
588 } 586 }
589 } 587 }
590 588
591 589
592 // Check the type argument vector 'arguments' against the corresponding bounds 590 // Check the type argument vector 'arguments' against the corresponding bounds
593 // of the type parameters of class 'cls' and, recursively, of its superclasses. 591 // of the type parameters of class 'cls' and, recursively, of its superclasses.
594 // Replace a type argument that cannot be checked at compile time by a 592 // Replace a type argument that cannot be checked at compile time by a
595 // BoundedType, thereby postponing the bound check to run time. 593 // BoundedType, thereby postponing the bound check to run time.
596 // Return a bound error if a type argument is not within bound at compile time. 594 // Return a bound error if a type argument is not within bound at compile time.
597 void ClassFinalizer::CheckTypeArgumentBounds( 595 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls,
598 const Class& cls, 596 const TypeArguments& arguments,
599 const AbstractTypeArguments& arguments, 597 Error* bound_error) {
600 Error* bound_error) {
601 if (!cls.is_type_finalized()) { 598 if (!cls.is_type_finalized()) {
602 FinalizeUpperBounds(cls); 599 FinalizeUpperBounds(cls);
603 } 600 }
604 // Note that when finalizing a type, we need to verify the bounds in both 601 // Note that when finalizing a type, we need to verify the bounds in both
605 // production mode and checked mode, because the finalized type may be written 602 // production mode and checked mode, because the finalized type may be written
606 // to a snapshot. It would be wrong to ignore bounds when generating the 603 // to a snapshot. It would be wrong to ignore bounds when generating the
607 // snapshot in production mode and then use the unchecked type in checked mode 604 // snapshot in production mode and then use the unchecked type in checked mode
608 // after reading it from the snapshot. 605 // after reading it from the snapshot.
609 // However, we do not immediately report a bound error, which would be wrong 606 // However, we do not immediately report a bound error, which would be wrong
610 // in production mode, but simply postpone the bound checking to runtime. 607 // in production mode, but simply postpone the bound checking to runtime.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 680 AbstractType& super_type = AbstractType::Handle(cls.super_type());
684 if (!super_type.IsNull()) { 681 if (!super_type.IsNull()) {
685 const Class& super_class = Class::Handle(super_type.type_class()); 682 const Class& super_class = Class::Handle(super_type.type_class());
686 CheckTypeArgumentBounds(super_class, arguments, bound_error); 683 CheckTypeArgumentBounds(super_class, arguments, bound_error);
687 } 684 }
688 } 685 }
689 686
690 687
691 void ClassFinalizer::CheckTypeBounds(const Class& cls, const Type& type) { 688 void ClassFinalizer::CheckTypeBounds(const Class& cls, const Type& type) {
692 ASSERT(type.IsFinalized()); 689 ASSERT(type.IsFinalized());
693 AbstractTypeArguments& arguments = 690 TypeArguments& arguments = TypeArguments::Handle(type.arguments());
694 AbstractTypeArguments::Handle(type.arguments());
695 if (arguments.IsNull()) { 691 if (arguments.IsNull()) {
696 return; 692 return;
697 } 693 }
698 Class& owner_class = Class::Handle(); 694 Class& owner_class = Class::Handle();
699 Class& type_class = Class::Handle(type.type_class()); 695 Class& type_class = Class::Handle(type.type_class());
700 if (type_class.IsSignatureClass()) { 696 if (type_class.IsSignatureClass()) {
701 const Function& signature_fun = 697 const Function& signature_fun =
702 Function::Handle(type_class.signature_function()); 698 Function::Handle(type_class.signature_function());
703 ASSERT(!signature_fun.is_static()); 699 ASSERT(!signature_fun.is_static());
704 owner_class = signature_fun.Owner(); 700 owner_class = signature_fun.Owner();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 819
824 // The finalized type argument vector needs num_type_arguments types. 820 // The finalized type argument vector needs num_type_arguments types.
825 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 821 const intptr_t num_type_arguments = type_class.NumTypeArguments();
826 // The type class has num_type_parameters type parameters. 822 // The type class has num_type_parameters type parameters.
827 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 823 const intptr_t num_type_parameters = type_class.NumTypeParameters();
828 824
829 // Initialize the type argument vector. 825 // Initialize the type argument vector.
830 // Check the number of parsed type arguments, if any. 826 // Check the number of parsed type arguments, if any.
831 // Specifying no type arguments indicates a raw type, which is not an error. 827 // Specifying no type arguments indicates a raw type, which is not an error.
832 // However, type parameter bounds are checked below, even for a raw type. 828 // However, type parameter bounds are checked below, even for a raw type.
833 AbstractTypeArguments& arguments = 829 TypeArguments& arguments =
834 AbstractTypeArguments::Handle(parameterized_type.arguments()); 830 TypeArguments::Handle(parameterized_type.arguments());
835 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 831 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
836 // Wrong number of type arguments. The type is mapped to the raw type. 832 // Wrong number of type arguments. The type is mapped to the raw type.
837 if (FLAG_error_on_bad_type) { 833 if (FLAG_error_on_bad_type) {
838 const Script& script = Script::Handle(cls.script()); 834 const Script& script = Script::Handle(cls.script());
839 const String& type_class_name = String::Handle(type_class.Name()); 835 const String& type_class_name = String::Handle(type_class.Name());
840 ReportError(Error::Handle(), // No previous error. 836 ReportError(Error::Handle(), // No previous error.
841 script, parameterized_type.token_pos(), 837 script, parameterized_type.token_pos(),
842 "wrong number of type arguments for class '%s'", 838 "wrong number of type arguments for class '%s'",
843 type_class_name.ToCString()); 839 type_class_name.ToCString());
844 } 840 }
845 // Make the type raw and continue without reporting any error. 841 // Make the type raw and continue without reporting any error.
846 // A static warning should have been reported. 842 // A static warning should have been reported.
847 arguments = AbstractTypeArguments::null(); 843 arguments = TypeArguments::null();
848 parameterized_type.set_arguments(arguments); 844 parameterized_type.set_arguments(arguments);
849 } 845 }
850 846
851 // The full type argument vector consists of the type arguments of the 847 // The full type argument vector consists of the type arguments of the
852 // super types of type_class, which are initialized from the parsed 848 // super types of type_class, which are initialized from the parsed
853 // type arguments, followed by the parsed type arguments. 849 // type arguments, followed by the parsed type arguments.
854 TypeArguments& full_arguments = TypeArguments::Handle(); 850 TypeArguments& full_arguments = TypeArguments::Handle();
855 Error& bound_error = Error::Handle(); 851 Error& bound_error = Error::Handle();
856 if (num_type_arguments > 0) { 852 if (num_type_arguments > 0) {
857 // If no type arguments were parsed and if the super types do not prepend 853 // If no type arguments were parsed and if the super types do not prepend
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 // function type to refer to itself via its parameter types and result type. 952 // function type to refer to itself via its parameter types and result type.
957 if (type_class.IsSignatureClass()) { 953 if (type_class.IsSignatureClass()) {
958 // The class may be created while parsing a function body, after all 954 // The class may be created while parsing a function body, after all
959 // pending classes have already been finalized. 955 // pending classes have already been finalized.
960 FinalizeTypesInClass(type_class); 956 FinalizeTypesInClass(type_class);
961 } 957 }
962 958
963 if (FLAG_trace_type_finalization) { 959 if (FLAG_trace_type_finalization) {
964 OS::Print("Done finalizing type '%s' with %" Pd " type args: %s\n", 960 OS::Print("Done finalizing type '%s' with %" Pd " type args: %s\n",
965 String::Handle(parameterized_type.Name()).ToCString(), 961 String::Handle(parameterized_type.Name()).ToCString(),
966 parameterized_type.arguments() == AbstractTypeArguments::null() ? 962 parameterized_type.arguments() == TypeArguments::null() ?
967 0 : num_type_arguments, 963 0 : num_type_arguments,
968 parameterized_type.ToCString()); 964 parameterized_type.ToCString());
969 } 965 }
970 966
971 if (finalization >= kCanonicalize) { 967 if (finalization >= kCanonicalize) {
972 return parameterized_type.Canonicalize(); 968 return parameterized_type.Canonicalize();
973 } else { 969 } else {
974 return parameterized_type.raw(); 970 return parameterized_type.raw();
975 } 971 }
976 } 972 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 } 1039 }
1044 return Class::null(); 1040 return Class::null();
1045 } 1041 }
1046 1042
1047 1043
1048 // Resolve the upper bounds of the type parameters of class cls. 1044 // Resolve the upper bounds of the type parameters of class cls.
1049 void ClassFinalizer::ResolveUpperBounds(const Class& cls) { 1045 void ClassFinalizer::ResolveUpperBounds(const Class& cls) {
1050 const intptr_t num_type_params = cls.NumTypeParameters(); 1046 const intptr_t num_type_params = cls.NumTypeParameters();
1051 TypeParameter& type_param = TypeParameter::Handle(); 1047 TypeParameter& type_param = TypeParameter::Handle();
1052 AbstractType& bound = AbstractType::Handle(); 1048 AbstractType& bound = AbstractType::Handle();
1053 const AbstractTypeArguments& type_params = 1049 const TypeArguments& type_params =
1054 AbstractTypeArguments::Handle(cls.type_parameters()); 1050 TypeArguments::Handle(cls.type_parameters());
1055 ASSERT((type_params.IsNull() && (num_type_params == 0)) || 1051 ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
1056 (type_params.Length() == num_type_params)); 1052 (type_params.Length() == num_type_params));
1057 // In a first pass, resolve all bounds. This guarantees that finalization 1053 // In a first pass, resolve all bounds. This guarantees that finalization
1058 // of mutually referencing bounds will not encounter an unresolved bound. 1054 // of mutually referencing bounds will not encounter an unresolved bound.
1059 for (intptr_t i = 0; i < num_type_params; i++) { 1055 for (intptr_t i = 0; i < num_type_params; i++) {
1060 type_param ^= type_params.TypeAt(i); 1056 type_param ^= type_params.TypeAt(i);
1061 bound = type_param.bound(); 1057 bound = type_param.bound();
1062 ResolveType(cls, bound); 1058 ResolveType(cls, bound);
1063 } 1059 }
1064 } 1060 }
1065 1061
1066 1062
1067 // Finalize the upper bounds of the type parameters of class cls. 1063 // Finalize the upper bounds of the type parameters of class cls.
1068 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { 1064 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) {
1069 const intptr_t num_type_params = cls.NumTypeParameters(); 1065 const intptr_t num_type_params = cls.NumTypeParameters();
1070 TypeParameter& type_param = TypeParameter::Handle(); 1066 TypeParameter& type_param = TypeParameter::Handle();
1071 AbstractType& bound = AbstractType::Handle(); 1067 AbstractType& bound = AbstractType::Handle();
1072 const AbstractTypeArguments& type_params = 1068 const TypeArguments& type_params =
1073 AbstractTypeArguments::Handle(cls.type_parameters()); 1069 TypeArguments::Handle(cls.type_parameters());
1074 ASSERT((type_params.IsNull() && (num_type_params == 0)) || 1070 ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
1075 (type_params.Length() == num_type_params)); 1071 (type_params.Length() == num_type_params));
1076 for (intptr_t i = 0; i < num_type_params; i++) { 1072 for (intptr_t i = 0; i < num_type_params; i++) {
1077 type_param ^= type_params.TypeAt(i); 1073 type_param ^= type_params.TypeAt(i);
1078 bound = type_param.bound(); 1074 bound = type_param.bound();
1079 if (bound.IsFinalized() || bound.IsBeingFinalized()) { 1075 if (bound.IsFinalized() || bound.IsBeingFinalized()) {
1080 // A bound involved in F-bounded quantification may form a cycle. 1076 // A bound involved in F-bounded quantification may form a cycle.
1081 continue; 1077 continue;
1082 } 1078 }
1083 bound = FinalizeType(cls, bound, kCanonicalize); 1079 bound = FinalizeType(cls, bound, kCanonicalize);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 Error& error = Error::Handle(); 1180 Error& error = Error::Handle();
1185 if (type.IsMalformedOrMalbounded()) { 1181 if (type.IsMalformedOrMalbounded()) {
1186 error = type.error(); 1182 error = type.error();
1187 } else { 1183 } else {
1188 ASSERT(type.IsInstantiated()); 1184 ASSERT(type.IsInstantiated());
1189 } 1185 }
1190 const Instance& const_value = Instance::Handle(field.value()); 1186 const Instance& const_value = Instance::Handle(field.value());
1191 if (!error.IsNull() || 1187 if (!error.IsNull() ||
1192 (!type.IsDynamicType() && 1188 (!type.IsDynamicType() &&
1193 !const_value.IsInstanceOf(type, 1189 !const_value.IsInstanceOf(type,
1194 AbstractTypeArguments::Handle(), 1190 Object::null_type_arguments(),
1195 &error))) { 1191 &error))) {
1196 if (FLAG_error_on_bad_type) { 1192 if (FLAG_error_on_bad_type) {
1197 const AbstractType& const_value_type = AbstractType::Handle( 1193 const AbstractType& const_value_type = AbstractType::Handle(
1198 const_value.GetType()); 1194 const_value.GetType());
1199 const String& const_value_type_name = String::Handle( 1195 const String& const_value_type_name = String::Handle(
1200 const_value_type.UserVisibleName()); 1196 const_value_type.UserVisibleName());
1201 const String& type_name = String::Handle(type.UserVisibleName()); 1197 const String& type_name = String::Handle(type.UserVisibleName());
1202 const Script& script = Script::Handle(cls.script()); 1198 const Script& script = Script::Handle(cls.script());
1203 ReportError(error, script, field.token_pos(), 1199 ReportError(error, script, field.token_pos(),
1204 "error initializing static %s field '%s': " 1200 "error initializing static %s field '%s': "
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 // Example: 1375 // Example:
1380 // class S<T> { } 1376 // class S<T> { }
1381 // class M<T> { } 1377 // class M<T> { }
1382 // class C<E> extends S<E> with M<List<E>> { } 1378 // class C<E> extends S<E> with M<List<E>> { }
1383 // results in 1379 // results in
1384 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> 1380 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T>
1385 // class C<E> extends S&M<E, List<E>> { } 1381 // class C<E> extends S&M<E, List<E>> { }
1386 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and 1382 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and
1387 // T, and use them as type arguments in S<T`> and M<T>. 1383 // T, and use them as type arguments in S<T`> and M<T>.
1388 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { 1384 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) {
1389 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); 1385 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null());
1390 Isolate* isolate = Isolate::Current(); 1386 Isolate* isolate = Isolate::Current();
1391 const AbstractType& super_type = AbstractType::Handle(isolate, 1387 const AbstractType& super_type = AbstractType::Handle(isolate,
1392 mixin_app_class.super_type()); 1388 mixin_app_class.super_type());
1393 ASSERT(super_type.IsResolved()); 1389 ASSERT(super_type.IsResolved());
1394 const Class& super_class = Class::Handle(isolate, super_type.type_class()); 1390 const Class& super_class = Class::Handle(isolate, super_type.type_class());
1395 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 1391 const intptr_t num_super_type_params = super_class.NumTypeParameters();
1396 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); 1392 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin());
1397 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); 1393 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class());
1398 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); 1394 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
1399 // The mixin class cannot be Object and this was checked earlier. 1395 // The mixin class cannot be Object and this was checked earlier.
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 // CloneMixinAppTypeParameters on the inserted class, as long as the super 1653 // CloneMixinAppTypeParameters on the inserted class, as long as the super
1658 // type class is set properly. 1654 // type class is set properly.
1659 inserted_class.set_super_type(super_type); // Super class only is used. 1655 inserted_class.set_super_type(super_type); // Super class only is used.
1660 1656
1661 // The mixin type and interface type must also be set before calling 1657 // The mixin type and interface type must also be set before calling
1662 // CloneMixinAppTypeParameters. 1658 // CloneMixinAppTypeParameters.
1663 // After FinalizeTypesInClass, they will refer to the type parameters of 1659 // After FinalizeTypesInClass, they will refer to the type parameters of
1664 // the mixin class typedef. 1660 // the mixin class typedef.
1665 const Type& generic_mixin_type = Type::Handle(isolate, 1661 const Type& generic_mixin_type = Type::Handle(isolate,
1666 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()), 1662 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()),
1667 Object::null_abstract_type_arguments(), 1663 Object::null_type_arguments(),
1668 aliased_mixin_type.token_pos())); 1664 aliased_mixin_type.token_pos()));
1669 inserted_class.set_mixin(generic_mixin_type); 1665 inserted_class.set_mixin(generic_mixin_type);
1670 // The interface will be set in CloneMixinAppTypeParameters. 1666 // The interface will be set in CloneMixinAppTypeParameters.
1671 } 1667 }
1672 1668
1673 // Finalize the types and call CloneMixinAppTypeParameters. 1669 // Finalize the types and call CloneMixinAppTypeParameters.
1674 FinalizeTypesInClass(inserted_class); 1670 FinalizeTypesInClass(inserted_class);
1675 1671
1676 // The super type of this mixin application class must point to the 1672 // The super type of this mixin application class must point to the
1677 // inserted class. The super type arguments are the concatenation of the 1673 // inserted class. The super type arguments are the concatenation of the
(...skipping 29 matching lines...) Expand all
1707 const Class& aliased_mixin_type_class = Class::Handle(isolate, 1703 const Class& aliased_mixin_type_class = Class::Handle(isolate,
1708 aliased_mixin_type.type_class()); 1704 aliased_mixin_type.type_class());
1709 const intptr_t num_aliased_mixin_type_params = 1705 const intptr_t num_aliased_mixin_type_params =
1710 aliased_mixin_type_class.NumTypeParameters(); 1706 aliased_mixin_type_class.NumTypeParameters();
1711 const intptr_t num_aliased_mixin_type_args = 1707 const intptr_t num_aliased_mixin_type_args =
1712 aliased_mixin_type_class.NumTypeArguments(); 1708 aliased_mixin_type_class.NumTypeArguments();
1713 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; 1709 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params;
1714 ASSERT(inserted_class.NumTypeParameters() == 1710 ASSERT(inserted_class.NumTypeParameters() ==
1715 (num_super_type_params + num_aliased_mixin_type_params)); 1711 (num_super_type_params + num_aliased_mixin_type_params));
1716 // The aliased_mixin_type may be raw. 1712 // The aliased_mixin_type may be raw.
1717 const AbstractTypeArguments& mixin_class_super_type_args = 1713 const TypeArguments& mixin_class_super_type_args =
1718 AbstractTypeArguments::Handle(isolate, 1714 TypeArguments::Handle(isolate,
1719 AbstractType::Handle(isolate, mixin_class.super_type()).arguments()); 1715 AbstractType::Handle(isolate, mixin_class.super_type()).arguments());
1720 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate); 1716 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate);
1721 if ((num_aliased_mixin_type_params > 0) && 1717 if ((num_aliased_mixin_type_params > 0) &&
1722 !mixin_class_super_type_args.IsNull()) { 1718 !mixin_class_super_type_args.IsNull()) {
1723 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); 1719 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params);
1724 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { 1720 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
1725 type = mixin_class_super_type_args.TypeAt(offset + i); 1721 type = mixin_class_super_type_args.TypeAt(offset + i);
1726 new_mixin_type_args.SetTypeAt(i, type); 1722 new_mixin_type_args.SetTypeAt(i, type);
1727 } 1723 }
1728 } 1724 }
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 GrowableArray<intptr_t>* visited) { 2213 GrowableArray<intptr_t>* visited) {
2218 ASSERT(visited != NULL); 2214 ASSERT(visited != NULL);
2219 ResolveType(cls, type); 2215 ResolveType(cls, type);
2220 if (type.IsType() && !type.IsMalformed()) { 2216 if (type.IsType() && !type.IsMalformed()) {
2221 const Class& type_class = Class::Handle(type.type_class()); 2217 const Class& type_class = Class::Handle(type.type_class());
2222 if (!type_class.is_type_finalized() && 2218 if (!type_class.is_type_finalized() &&
2223 type_class.IsSignatureClass() && 2219 type_class.IsSignatureClass() &&
2224 !IsAliasCycleFree(type_class, visited)) { 2220 !IsAliasCycleFree(type_class, visited)) {
2225 return false; 2221 return false;
2226 } 2222 }
2227 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( 2223 const TypeArguments& type_args = TypeArguments::Handle(type.arguments());
2228 type.arguments());
2229 if (!type_args.IsNull()) { 2224 if (!type_args.IsNull()) {
2230 AbstractType& type_arg = AbstractType::Handle(); 2225 AbstractType& type_arg = AbstractType::Handle();
2231 for (intptr_t i = 0; i < type_args.Length(); i++) { 2226 for (intptr_t i = 0; i < type_args.Length(); i++) {
2232 type_arg = type_args.TypeAt(i); 2227 type_arg = type_args.TypeAt(i);
2233 if (!IsTypeCycleFree(cls, type_arg, visited)) { 2228 if (!IsTypeCycleFree(cls, type_arg, visited)) {
2234 return false; 2229 return false;
2235 } 2230 }
2236 } 2231 }
2237 } 2232 }
2238 } 2233 }
(...skipping 15 matching lines...) Expand all
2254 } 2249 }
2255 } 2250 }
2256 2251
2257 // Visit the bounds, result type, and parameter types of this signature type. 2252 // Visit the bounds, result type, and parameter types of this signature type.
2258 visited->Add(cls.id()); 2253 visited->Add(cls.id());
2259 AbstractType& type = AbstractType::Handle(); 2254 AbstractType& type = AbstractType::Handle();
2260 2255
2261 // Check the bounds of this signature type. 2256 // Check the bounds of this signature type.
2262 const intptr_t num_type_params = cls.NumTypeParameters(); 2257 const intptr_t num_type_params = cls.NumTypeParameters();
2263 TypeParameter& type_param = TypeParameter::Handle(); 2258 TypeParameter& type_param = TypeParameter::Handle();
2264 const AbstractTypeArguments& type_params = 2259 const TypeArguments& type_params =
2265 AbstractTypeArguments::Handle(cls.type_parameters()); 2260 TypeArguments::Handle(cls.type_parameters());
2266 ASSERT((type_params.IsNull() && (num_type_params == 0)) || 2261 ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
2267 (type_params.Length() == num_type_params)); 2262 (type_params.Length() == num_type_params));
2268 for (intptr_t i = 0; i < num_type_params; i++) { 2263 for (intptr_t i = 0; i < num_type_params; i++) {
2269 type_param ^= type_params.TypeAt(i); 2264 type_param ^= type_params.TypeAt(i);
2270 type = type_param.bound(); 2265 type = type_param.bound();
2271 if (!IsTypeCycleFree(cls, type, visited)) { 2266 if (!IsTypeCycleFree(cls, type, visited)) {
2272 return false; 2267 return false;
2273 } 2268 }
2274 } 2269 }
2275 // Check the result type of the function of this signature type. 2270 // Check the result type of the function of this signature type.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 return true; 2317 return true;
2323 } 2318 }
2324 2319
2325 2320
2326 void ClassFinalizer::CollectTypeArguments( 2321 void ClassFinalizer::CollectTypeArguments(
2327 const Class& cls, 2322 const Class& cls,
2328 const Type& type, 2323 const Type& type,
2329 const GrowableObjectArray& collected_args) { 2324 const GrowableObjectArray& collected_args) {
2330 ASSERT(type.HasResolvedTypeClass()); 2325 ASSERT(type.HasResolvedTypeClass());
2331 Class& type_class = Class::Handle(type.type_class()); 2326 Class& type_class = Class::Handle(type.type_class());
2332 AbstractTypeArguments& type_args = 2327 TypeArguments& type_args = TypeArguments::Handle(type.arguments());
2333 AbstractTypeArguments::Handle(type.arguments());
2334 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 2328 const intptr_t num_type_parameters = type_class.NumTypeParameters();
2335 const intptr_t num_type_arguments = 2329 const intptr_t num_type_arguments =
2336 type_args.IsNull() ? 0 : type_args.Length(); 2330 type_args.IsNull() ? 0 : type_args.Length();
2337 AbstractType& arg = AbstractType::Handle(); 2331 AbstractType& arg = AbstractType::Handle();
2338 if (num_type_arguments > 0) { 2332 if (num_type_arguments > 0) {
2339 if (num_type_arguments == num_type_parameters) { 2333 if (num_type_arguments == num_type_parameters) {
2340 for (intptr_t i = 0; i < num_type_arguments; i++) { 2334 for (intptr_t i = 0; i < num_type_arguments; i++) {
2341 arg = type_args.TypeAt(i); 2335 arg = type_args.TypeAt(i);
2342 arg = arg.CloneUnfinalized(); 2336 arg = arg.CloneUnfinalized();
2343 ASSERT(!arg.IsBeingFinalized()); 2337 ASSERT(!arg.IsBeingFinalized());
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2437 mixin_type_class_name); 2431 mixin_type_class_name);
2438 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); 2432 mixin_app_class = library.LookupLocalClass(mixin_app_class_name);
2439 if (mixin_app_class.IsNull()) { 2433 if (mixin_app_class.IsNull()) {
2440 mixin_app_class_name = Symbols::New(mixin_app_class_name); 2434 mixin_app_class_name = Symbols::New(mixin_app_class_name);
2441 mixin_app_class = Class::New(mixin_app_class_name, 2435 mixin_app_class = Class::New(mixin_app_class_name,
2442 script, 2436 script,
2443 mixin_type.token_pos()); 2437 mixin_type.token_pos());
2444 mixin_app_class.set_super_type(mixin_super_type); 2438 mixin_app_class.set_super_type(mixin_super_type);
2445 mixin_type_class = mixin_type.type_class(); 2439 mixin_type_class = mixin_type.type_class();
2446 generic_mixin_type = Type::New(mixin_type_class, 2440 generic_mixin_type = Type::New(mixin_type_class,
2447 Object::null_abstract_type_arguments(), 2441 Object::null_type_arguments(),
2448 mixin_type.token_pos()); 2442 mixin_type.token_pos());
2449 mixin_app_class.set_mixin(generic_mixin_type); 2443 mixin_app_class.set_mixin(generic_mixin_type);
2450 mixin_app_class.set_is_synthesized_class(); 2444 mixin_app_class.set_is_synthesized_class();
2451 library.AddClass(mixin_app_class); 2445 library.AddClass(mixin_app_class);
2452 2446
2453 // No need to add the new class to pending_classes, since it will be 2447 // No need to add the new class to pending_classes, since it will be
2454 // processed via the super_type chain of a pending class. 2448 // processed via the super_type chain of a pending class.
2455 2449
2456 if (FLAG_trace_class_finalization) { 2450 if (FLAG_trace_class_finalization) {
2457 OS::Print("Creating mixin application %s\n", 2451 OS::Print("Creating mixin application %s\n",
2458 mixin_app_class.ToCString()); 2452 mixin_app_class.ToCString());
2459 } 2453 }
2460 } 2454 }
2461 // This mixin application class becomes the type class of the super type of 2455 // This mixin application class becomes the type class of the super type of
2462 // the next mixin application class. It is however too early to provide the 2456 // the next mixin application class. It is however too early to provide the
2463 // correct super type arguments. We use the raw type for now. 2457 // correct super type arguments. We use the raw type for now.
2464 mixin_super_type = Type::New(mixin_app_class, 2458 mixin_super_type = Type::New(mixin_app_class,
2465 Object::null_abstract_type_arguments(), 2459 Object::null_type_arguments(),
2466 mixin_type.token_pos()); 2460 mixin_type.token_pos());
2467 } 2461 }
2468 AbstractType& type_arg = AbstractType::Handle(); 2462 AbstractType& type_arg = AbstractType::Handle();
2469 const TypeArguments& mixin_app_args = 2463 const TypeArguments& mixin_app_args =
2470 TypeArguments::Handle(TypeArguments::New(type_args.Length())); 2464 TypeArguments::Handle(TypeArguments::New(type_args.Length()));
2471 for (intptr_t i = 0; i < type_args.Length(); i++) { 2465 for (intptr_t i = 0; i < type_args.Length(); i++) {
2472 type_arg ^= type_args.At(i); 2466 type_arg ^= type_args.At(i);
2473 mixin_app_args.SetTypeAt(i, type_arg); 2467 mixin_app_args.SetTypeAt(i, type_arg);
2474 } 2468 }
2475 if (FLAG_trace_class_finalization) { 2469 if (FLAG_trace_class_finalization) {
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2748 prev_error, script, type.token_pos(), 2742 prev_error, script, type.token_pos(),
2749 LanguageError::kMalformedType, Heap::kOld, 2743 LanguageError::kMalformedType, Heap::kOld,
2750 format, args)); 2744 format, args));
2751 if (FLAG_error_on_bad_type) { 2745 if (FLAG_error_on_bad_type) {
2752 ReportError(error); 2746 ReportError(error);
2753 } 2747 }
2754 type.set_error(error); 2748 type.set_error(error);
2755 // Make the type raw, since it may not be possible to 2749 // Make the type raw, since it may not be possible to
2756 // properly finalize its type arguments. 2750 // properly finalize its type arguments.
2757 type.set_type_class(Class::Handle(Object::dynamic_class())); 2751 type.set_type_class(Class::Handle(Object::dynamic_class()));
2758 type.set_arguments(Object::null_abstract_type_arguments()); 2752 type.set_arguments(Object::null_type_arguments());
2759 if (!type.IsFinalized()) { 2753 if (!type.IsFinalized()) {
2760 type.SetIsFinalized(); 2754 type.SetIsFinalized();
2761 // Do not canonicalize malformed types, since they may not be resolved. 2755 // Do not canonicalize malformed types, since they may not be resolved.
2762 } else { 2756 } else {
2763 // The only case where the malformed type was already finalized is when its 2757 // The only case where the malformed type was already finalized is when its
2764 // type arguments are not within bounds. In that case, we have a prev_error. 2758 // type arguments are not within bounds. In that case, we have a prev_error.
2765 ASSERT(!prev_error.IsNull()); 2759 ASSERT(!prev_error.IsNull());
2766 } 2760 }
2767 } 2761 }
2768 2762
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2896 expected_name ^= String::New("_offset"); 2890 expected_name ^= String::New("_offset");
2897 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2891 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2898 field ^= fields_array.At(2); 2892 field ^= fields_array.At(2);
2899 ASSERT(field.Offset() == TypedDataView::length_offset()); 2893 ASSERT(field.Offset() == TypedDataView::length_offset());
2900 name ^= field.name(); 2894 name ^= field.name();
2901 ASSERT(name.Equals("length")); 2895 ASSERT(name.Equals("length"));
2902 #endif 2896 #endif
2903 } 2897 }
2904 2898
2905 } // namespace dart 2899 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698