OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/hash_table.h" | 9 #include "vm/hash_table.h" |
10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 if (!target.IsNull()) { | 357 if (!target.IsNull()) { |
358 // Already resolved. | 358 // Already resolved. |
359 return; | 359 return; |
360 } | 360 } |
361 | 361 |
362 // Target is not resolved yet. | 362 // Target is not resolved yet. |
363 if (FLAG_trace_class_finalization) { | 363 if (FLAG_trace_class_finalization) { |
364 THR_Print("Resolving redirecting factory: %s\n", | 364 THR_Print("Resolving redirecting factory: %s\n", |
365 String::Handle(factory.name()).ToCString()); | 365 String::Handle(factory.name()).ToCString()); |
366 } | 366 } |
367 type ^= FinalizeType(cls, type, kCanonicalize); | 367 type ^= FinalizeType(cls, type); |
368 factory.SetRedirectionType(type); | 368 factory.SetRedirectionType(type); |
369 if (type.IsMalformedOrMalbounded()) { | 369 if (type.IsMalformedOrMalbounded()) { |
370 ASSERT(factory.RedirectionTarget() == Function::null()); | 370 ASSERT(factory.RedirectionTarget() == Function::null()); |
371 return; | 371 return; |
372 } | 372 } |
373 ASSERT(!type.IsTypeParameter()); // Resolved in parser. | 373 ASSERT(!type.IsTypeParameter()); // Resolved in parser. |
374 if (type.IsDynamicType()) { | 374 if (type.IsDynamicType()) { |
375 // Replace the type with a malformed type and compile a throw when called. | 375 // Replace the type with a malformed type and compile a throw when called. |
376 type = NewFinalizedMalformedType(Error::Handle(), // No previous error. | 376 type = NewFinalizedMalformedType(Error::Handle(), // No previous error. |
377 Script::Handle(cls.script()), | 377 Script::Handle(cls.script()), |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 ASSERT(target_type.IsMalformed()); | 453 ASSERT(target_type.IsMalformed()); |
454 } else { | 454 } else { |
455 // If the target type refers to type parameters, substitute them with the | 455 // If the target type refers to type parameters, substitute them with the |
456 // type arguments of the redirection type. | 456 // type arguments of the redirection type. |
457 if (!target_type.IsInstantiated()) { | 457 if (!target_type.IsInstantiated()) { |
458 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); | 458 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
459 Error& bound_error = Error::Handle(); | 459 Error& bound_error = Error::Handle(); |
460 target_type ^= target_type.InstantiateFrom(type_args, &bound_error, NULL, | 460 target_type ^= target_type.InstantiateFrom(type_args, &bound_error, NULL, |
461 NULL, Heap::kOld); | 461 NULL, Heap::kOld); |
462 if (bound_error.IsNull()) { | 462 if (bound_error.IsNull()) { |
463 target_type ^= FinalizeType(cls, target_type, kCanonicalize); | 463 target_type ^= FinalizeType(cls, target_type); |
464 } else { | 464 } else { |
465 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); | 465 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); |
466 const Script& script = Script::Handle(target_class.script()); | 466 const Script& script = Script::Handle(target_class.script()); |
467 FinalizeMalformedType(bound_error, script, target_type, | 467 FinalizeMalformedType(bound_error, script, target_type, |
468 "cannot resolve redirecting factory"); | 468 "cannot resolve redirecting factory"); |
469 target_target = Function::null(); | 469 target_target = Function::null(); |
470 } | 470 } |
471 } | 471 } |
472 } | 472 } |
473 factory.SetRedirectionType(target_type); | 473 factory.SetRedirectionType(target_type); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 // The induced type set S consists of the super types of any type in S as well | 635 // The induced type set S consists of the super types of any type in S as well |
636 // as the type arguments of any parameterized type in S. | 636 // as the type arguments of any parameterized type in S. |
637 // The Dart Language Specification does not disallow the declaration and use of | 637 // The Dart Language Specification does not disallow the declaration and use of |
638 // non-contractive types (this may change). They are nevertheless disallowed | 638 // non-contractive types (this may change). They are nevertheless disallowed |
639 // as an implementation restriction in the VM since they cause divergence. | 639 // as an implementation restriction in the VM since they cause divergence. |
640 // A non-contractive type can be detected by looking at the queue of types | 640 // A non-contractive type can be detected by looking at the queue of types |
641 // pending finalization that are mutually recursive with the checked type. | 641 // pending finalization that are mutually recursive with the checked type. |
642 void ClassFinalizer::CheckRecursiveType(const Class& cls, | 642 void ClassFinalizer::CheckRecursiveType(const Class& cls, |
643 const AbstractType& type, | 643 const AbstractType& type, |
644 PendingTypes* pending_types) { | 644 PendingTypes* pending_types) { |
| 645 ASSERT(pending_types != NULL); |
645 Zone* zone = Thread::Current()->zone(); | 646 Zone* zone = Thread::Current()->zone(); |
646 if (FLAG_trace_type_finalization) { | 647 if (FLAG_trace_type_finalization) { |
647 THR_Print("Checking recursive type '%s': %s\n", | 648 THR_Print("Checking recursive type '%s': %s\n", |
648 String::Handle(type.Name()).ToCString(), type.ToCString()); | 649 String::Handle(type.Name()).ToCString(), type.ToCString()); |
649 } | 650 } |
650 const Class& type_cls = Class::Handle(zone, type.type_class()); | 651 const Class& type_cls = Class::Handle(zone, type.type_class()); |
651 const TypeArguments& arguments = | 652 const TypeArguments& arguments = |
652 TypeArguments::Handle(zone, type.arguments()); | 653 TypeArguments::Handle(zone, type.arguments()); |
653 // A type can only be recursive via its type arguments. | 654 // A type can only be recursive via its type arguments. |
654 ASSERT(!arguments.IsNull()); | 655 ASSERT(!arguments.IsNull()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 "wrong number of type arguments for class '%s'", | 736 "wrong number of type arguments for class '%s'", |
736 type_class_name.ToCString()); | 737 type_class_name.ToCString()); |
737 } | 738 } |
738 // Make the type raw and continue without reporting any error. | 739 // Make the type raw and continue without reporting any error. |
739 // A static warning should have been reported. | 740 // A static warning should have been reported. |
740 arguments = TypeArguments::null(); | 741 arguments = TypeArguments::null(); |
741 type.set_arguments(arguments); | 742 type.set_arguments(arguments); |
742 } | 743 } |
743 | 744 |
744 // Mark the type as being finalized in order to detect self reference and | 745 // Mark the type as being finalized in order to detect self reference and |
745 // postpone bound checking until after all types in the graph of | 746 // postpone bound checking (if required) until after all types in the graph of |
746 // mutually recursive types are finalized. | 747 // mutually recursive types are finalized. |
747 type.SetIsBeingFinalized(); | 748 type.SetIsBeingFinalized(); |
748 pending_types->Add(type); | 749 if (pending_types != NULL) { |
| 750 pending_types->Add(type); |
| 751 } |
749 | 752 |
750 // The full type argument vector consists of the type arguments of the | 753 // The full type argument vector consists of the type arguments of the |
751 // super types of type_class, which are initialized from the parsed | 754 // super types of type_class, which are initialized from the parsed |
752 // type arguments, followed by the parsed type arguments. | 755 // type arguments, followed by the parsed type arguments. |
753 TypeArguments& full_arguments = TypeArguments::Handle(zone); | 756 TypeArguments& full_arguments = TypeArguments::Handle(zone); |
754 if (FLAG_reify && (num_type_arguments > 0)) { | 757 if (FLAG_reify && (num_type_arguments > 0)) { |
755 // If no type arguments were parsed and if the super types do not prepend | 758 // If no type arguments were parsed and if the super types do not prepend |
756 // type arguments to the vector, we can leave the vector as null. | 759 // type arguments to the vector, we can leave the vector as null. |
757 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 760 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
758 full_arguments = TypeArguments::New(num_type_arguments); | 761 full_arguments = TypeArguments::New(num_type_arguments); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 *bound_error = type_arg.error(); | 1006 *bound_error = type_arg.error(); |
1004 ASSERT(!bound_error->IsNull()); | 1007 ASSERT(!bound_error->IsNull()); |
1005 } | 1008 } |
1006 } | 1009 } |
1007 cls_type_param = cls_type_params.TypeAt(i); | 1010 cls_type_param = cls_type_params.TypeAt(i); |
1008 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); | 1011 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); |
1009 ASSERT(type_param.IsFinalized()); | 1012 ASSERT(type_param.IsFinalized()); |
1010 declared_bound = type_param.bound(); | 1013 declared_bound = type_param.bound(); |
1011 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { | 1014 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { |
1012 if (!declared_bound.IsFinalized() && !declared_bound.IsBeingFinalized()) { | 1015 if (!declared_bound.IsFinalized() && !declared_bound.IsBeingFinalized()) { |
1013 declared_bound = FinalizeType(cls, declared_bound, kCanonicalize); | 1016 declared_bound = FinalizeType(cls, declared_bound); |
1014 type_param.set_bound(declared_bound); | 1017 type_param.set_bound(declared_bound); |
1015 } | 1018 } |
1016 ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized()); | 1019 ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized()); |
1017 Error& error = Error::Handle(); | 1020 Error& error = Error::Handle(); |
1018 // Note that the bound may be malformed, in which case the bound check | 1021 // Note that the bound may be malformed, in which case the bound check |
1019 // will return an error and the bound check will be postponed to run time. | 1022 // will return an error and the bound check will be postponed to run time. |
1020 if (declared_bound.IsInstantiated()) { | 1023 if (declared_bound.IsInstantiated()) { |
1021 instantiated_bound = declared_bound.raw(); | 1024 instantiated_bound = declared_bound.raw(); |
1022 } else { | 1025 } else { |
1023 instantiated_bound = declared_bound.InstantiateFrom( | 1026 instantiated_bound = declared_bound.InstantiateFrom( |
(...skipping 15 matching lines...) Expand all Loading... |
1039 !(type_arg.Equals(type_param) && | 1042 !(type_arg.Equals(type_param) && |
1040 instantiated_bound.Equals(declared_bound))) { | 1043 instantiated_bound.Equals(declared_bound))) { |
1041 // If type_arg is a type parameter, its declared bound may not be | 1044 // If type_arg is a type parameter, its declared bound may not be |
1042 // finalized yet. | 1045 // finalized yet. |
1043 if (type_arg.IsTypeParameter()) { | 1046 if (type_arg.IsTypeParameter()) { |
1044 const Class& type_arg_cls = Class::Handle( | 1047 const Class& type_arg_cls = Class::Handle( |
1045 TypeParameter::Cast(type_arg).parameterized_class()); | 1048 TypeParameter::Cast(type_arg).parameterized_class()); |
1046 AbstractType& bound = | 1049 AbstractType& bound = |
1047 AbstractType::Handle(TypeParameter::Cast(type_arg).bound()); | 1050 AbstractType::Handle(TypeParameter::Cast(type_arg).bound()); |
1048 if (!bound.IsFinalized() && !bound.IsBeingFinalized()) { | 1051 if (!bound.IsFinalized() && !bound.IsBeingFinalized()) { |
1049 bound = FinalizeType(type_arg_cls, bound, kCanonicalize); | 1052 bound = FinalizeType(type_arg_cls, bound); |
1050 TypeParameter::Cast(type_arg).set_bound(bound); | 1053 TypeParameter::Cast(type_arg).set_bound(bound); |
1051 } | 1054 } |
1052 } | 1055 } |
1053 // This may be called only if type needs to be finalized, therefore | 1056 // This may be called only if type needs to be finalized, therefore |
1054 // seems OK to allocate finalized types in old space. | 1057 // seems OK to allocate finalized types in old space. |
1055 if (!type_param.CheckBound(type_arg, instantiated_bound, &error, NULL, | 1058 if (!type_param.CheckBound(type_arg, instantiated_bound, &error, NULL, |
1056 Heap::kOld) && | 1059 Heap::kOld) && |
1057 error.IsNull()) { | 1060 error.IsNull()) { |
1058 // The bound cannot be checked at compile time; postpone to run time. | 1061 // The bound cannot be checked at compile time; postpone to run time. |
1059 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 1062 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 } | 1194 } |
1192 | 1195 |
1193 // We do not canonicalize type parameters. | 1196 // We do not canonicalize type parameters. |
1194 return type_parameter.raw(); | 1197 return type_parameter.raw(); |
1195 } | 1198 } |
1196 | 1199 |
1197 // At this point, we can only have a Type. | 1200 // At this point, we can only have a Type. |
1198 ASSERT(type.IsType()); | 1201 ASSERT(type.IsType()); |
1199 | 1202 |
1200 // This type is the root type of the type graph if no pending types queue is | 1203 // This type is the root type of the type graph if no pending types queue is |
1201 // allocated yet. | 1204 // allocated yet, and if canonicalization is required. |
1202 const bool is_root_type = (pending_types == NULL); | 1205 const bool is_root_type = |
| 1206 (pending_types == NULL) && (finalization >= kCanonicalize); |
1203 if (is_root_type) { | 1207 if (is_root_type) { |
1204 pending_types = new PendingTypes(zone, 4); | 1208 pending_types = new PendingTypes(zone, 4); |
1205 } | 1209 } |
1206 | 1210 |
1207 const intptr_t num_expanded_type_arguments = | 1211 const intptr_t num_expanded_type_arguments = |
1208 ExpandAndFinalizeTypeArguments(cls, type, pending_types); | 1212 ExpandAndFinalizeTypeArguments(cls, type, pending_types); |
1209 | 1213 |
1210 // If we are done finalizing a graph of mutually recursive types, check their | 1214 // If we are done finalizing a graph of mutually recursive types, check their |
1211 // bounds. | 1215 // bounds. |
1212 if (is_root_type) { | 1216 if (is_root_type) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 // Resolve formal parameter types. | 1287 // Resolve formal parameter types. |
1284 const intptr_t num_parameters = function.NumParameters(); | 1288 const intptr_t num_parameters = function.NumParameters(); |
1285 for (intptr_t i = 0; i < num_parameters; i++) { | 1289 for (intptr_t i = 0; i < num_parameters; i++) { |
1286 type = function.ParameterTypeAt(i); | 1290 type = function.ParameterTypeAt(i); |
1287 ResolveType(cls, type); | 1291 ResolveType(cls, type); |
1288 } | 1292 } |
1289 } | 1293 } |
1290 | 1294 |
1291 | 1295 |
1292 void ClassFinalizer::FinalizeSignature(const Class& cls, | 1296 void ClassFinalizer::FinalizeSignature(const Class& cls, |
1293 const Function& function) { | 1297 const Function& function, |
| 1298 FinalizationKind finalization) { |
1294 AbstractType& type = AbstractType::Handle(); | 1299 AbstractType& type = AbstractType::Handle(); |
1295 AbstractType& finalized_type = AbstractType::Handle(); | 1300 AbstractType& finalized_type = AbstractType::Handle(); |
1296 // Finalize upper bounds of function type parameters. | 1301 // Finalize upper bounds of function type parameters. |
1297 const intptr_t num_type_params = function.NumTypeParameters(); | 1302 const intptr_t num_type_params = function.NumTypeParameters(); |
1298 if (num_type_params > 0) { | 1303 if (num_type_params > 0) { |
1299 TypeParameter& type_param = TypeParameter::Handle(); | 1304 TypeParameter& type_param = TypeParameter::Handle(); |
1300 const TypeArguments& type_params = | 1305 const TypeArguments& type_params = |
1301 TypeArguments::Handle(function.type_parameters()); | 1306 TypeArguments::Handle(function.type_parameters()); |
1302 for (intptr_t i = 0; i < num_type_params; i++) { | 1307 for (intptr_t i = 0; i < num_type_params; i++) { |
1303 type_param ^= type_params.TypeAt(i); | 1308 type_param ^= type_params.TypeAt(i); |
1304 type = type_param.bound(); | 1309 type = type_param.bound(); |
1305 finalized_type = FinalizeType(cls, type, kCanonicalize); | 1310 finalized_type = FinalizeType(cls, type, finalization); |
1306 if (finalized_type.raw() != type.raw()) { | 1311 if (finalized_type.raw() != type.raw()) { |
1307 type_param.set_bound(finalized_type); | 1312 type_param.set_bound(finalized_type); |
1308 } | 1313 } |
1309 } | 1314 } |
1310 } | 1315 } |
1311 // Finalize result type. | 1316 // Finalize result type. |
1312 type = function.result_type(); | 1317 type = function.result_type(); |
1313 finalized_type = FinalizeType(cls, type, kCanonicalize); | 1318 finalized_type = FinalizeType(cls, type, finalization); |
1314 // The result type may be malformed or malbounded. | 1319 // The result type may be malformed or malbounded. |
1315 if (finalized_type.raw() != type.raw()) { | 1320 if (finalized_type.raw() != type.raw()) { |
1316 function.set_result_type(finalized_type); | 1321 function.set_result_type(finalized_type); |
1317 } | 1322 } |
1318 // Finalize formal parameter types. | 1323 // Finalize formal parameter types. |
1319 const intptr_t num_parameters = function.NumParameters(); | 1324 const intptr_t num_parameters = function.NumParameters(); |
1320 for (intptr_t i = 0; i < num_parameters; i++) { | 1325 for (intptr_t i = 0; i < num_parameters; i++) { |
1321 type = function.ParameterTypeAt(i); | 1326 type = function.ParameterTypeAt(i); |
1322 finalized_type = FinalizeType(cls, type, kCanonicalize); | 1327 finalized_type = FinalizeType(cls, type, finalization); |
1323 // The parameter type may be malformed or malbounded. | 1328 // The parameter type may be malformed or malbounded. |
1324 if (type.raw() != finalized_type.raw()) { | 1329 if (type.raw() != finalized_type.raw()) { |
1325 function.SetParameterTypeAt(i, finalized_type); | 1330 function.SetParameterTypeAt(i, finalized_type); |
1326 } | 1331 } |
1327 } | 1332 } |
1328 } | 1333 } |
1329 | 1334 |
1330 | 1335 |
1331 // Check if an instance field, getter, or method of same name exists | 1336 // Check if an instance field, getter, or method of same name exists |
1332 // in any super class. | 1337 // in any super class. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1444 Field& field = Field::Handle(zone); | 1449 Field& field = Field::Handle(zone); |
1445 AbstractType& type = AbstractType::Handle(zone); | 1450 AbstractType& type = AbstractType::Handle(zone); |
1446 String& name = String::Handle(zone); | 1451 String& name = String::Handle(zone); |
1447 String& getter_name = String::Handle(zone); | 1452 String& getter_name = String::Handle(zone); |
1448 String& setter_name = String::Handle(zone); | 1453 String& setter_name = String::Handle(zone); |
1449 Class& super_class = Class::Handle(zone); | 1454 Class& super_class = Class::Handle(zone); |
1450 const intptr_t num_fields = array.Length(); | 1455 const intptr_t num_fields = array.Length(); |
1451 for (intptr_t i = 0; i < num_fields; i++) { | 1456 for (intptr_t i = 0; i < num_fields; i++) { |
1452 field ^= array.At(i); | 1457 field ^= array.At(i); |
1453 type = field.type(); | 1458 type = field.type(); |
1454 type = FinalizeType(cls, type, kCanonicalize); | 1459 type = FinalizeType(cls, type); |
1455 field.SetFieldType(type); | 1460 field.SetFieldType(type); |
1456 name = field.name(); | 1461 name = field.name(); |
1457 if (field.is_static()) { | 1462 if (field.is_static()) { |
1458 getter_name = Field::GetterSymbol(name); | 1463 getter_name = Field::GetterSymbol(name); |
1459 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1464 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
1460 if (!super_class.IsNull()) { | 1465 if (!super_class.IsNull()) { |
1461 const String& class_name = String::Handle(zone, cls.Name()); | 1466 const String& class_name = String::Handle(zone, cls.Name()); |
1462 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1467 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1463 ReportError(cls, field.token_pos(), | 1468 ReportError(cls, field.token_pos(), |
1464 "static field '%s' of class '%s' conflicts with " | 1469 "static field '%s' of class '%s' conflicts with " |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 super_cls_name.ToCString()); | 1640 super_cls_name.ToCString()); |
1636 } | 1641 } |
1637 if (function.IsRedirectingFactory()) { | 1642 if (function.IsRedirectingFactory()) { |
1638 // The function may be a still unresolved redirecting factory. Do not | 1643 // The function may be a still unresolved redirecting factory. Do not |
1639 // yet try to resolve it in order to avoid cycles in class finalization. | 1644 // yet try to resolve it in order to avoid cycles in class finalization. |
1640 // However, the redirection type should be finalized. | 1645 // However, the redirection type should be finalized. |
1641 // If the redirection type is from a deferred library and is not | 1646 // If the redirection type is from a deferred library and is not |
1642 // yet loaded, do not attempt to resolve. | 1647 // yet loaded, do not attempt to resolve. |
1643 Type& type = Type::Handle(zone, function.RedirectionType()); | 1648 Type& type = Type::Handle(zone, function.RedirectionType()); |
1644 if (IsLoaded(type)) { | 1649 if (IsLoaded(type)) { |
1645 type ^= FinalizeType(cls, type, kCanonicalize); | 1650 type ^= FinalizeType(cls, type); |
1646 function.SetRedirectionType(type); | 1651 function.SetRedirectionType(type); |
1647 } | 1652 } |
1648 } | 1653 } |
1649 } else if (function.IsGetterFunction() || | 1654 } else if (function.IsGetterFunction() || |
1650 function.IsImplicitGetterFunction()) { | 1655 function.IsImplicitGetterFunction()) { |
1651 super_class = FindSuperOwnerOfFunction(cls, name); | 1656 super_class = FindSuperOwnerOfFunction(cls, name); |
1652 if (!super_class.IsNull()) { | 1657 if (!super_class.IsNull()) { |
1653 const String& class_name = String::Handle(zone, cls.Name()); | 1658 const String& class_name = String::Handle(zone, cls.Name()); |
1654 const String& super_cls_name = String::Handle(zone, super_class.Name()); | 1659 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1655 ReportError(cls, function.token_pos(), | 1660 ReportError(cls, function.token_pos(), |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1825 // is not a problem since they will get finalized shortly as the mixin | 1830 // is not a problem since they will get finalized shortly as the mixin |
1826 // application class gets finalized. | 1831 // application class gets finalized. |
1827 if (has_uninstantiated_bounds) { | 1832 if (has_uninstantiated_bounds) { |
1828 Error& bound_error = Error::Handle(zone); | 1833 Error& bound_error = Error::Handle(zone); |
1829 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1834 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
1830 param ^= mixin_type_args.TypeAt(i); | 1835 param ^= mixin_type_args.TypeAt(i); |
1831 param_bound = param.bound(); | 1836 param_bound = param.bound(); |
1832 if (!param_bound.IsInstantiated()) { | 1837 if (!param_bound.IsInstantiated()) { |
1833 // Make sure the bound is finalized before instantiating it. | 1838 // Make sure the bound is finalized before instantiating it. |
1834 if (!param_bound.IsFinalized() && !param_bound.IsBeingFinalized()) { | 1839 if (!param_bound.IsFinalized() && !param_bound.IsBeingFinalized()) { |
1835 param_bound = | 1840 param_bound = FinalizeType(mixin_app_class, param_bound); |
1836 FinalizeType(mixin_app_class, param_bound, kCanonicalize); | |
1837 param.set_bound(param_bound); // In case part of recursive type. | 1841 param.set_bound(param_bound); // In case part of recursive type. |
1838 } | 1842 } |
1839 param_bound = param_bound.InstantiateFrom( | 1843 param_bound = param_bound.InstantiateFrom( |
1840 instantiator, &bound_error, NULL, NULL, Heap::kOld); | 1844 instantiator, &bound_error, NULL, NULL, Heap::kOld); |
1841 // The instantiator contains only TypeParameter objects and no | 1845 // The instantiator contains only TypeParameter objects and no |
1842 // BoundedType objects, so no bound error may occur. | 1846 // BoundedType objects, so no bound error may occur. |
1843 ASSERT(!param_bound.IsBoundedType()); | 1847 ASSERT(!param_bound.IsBoundedType()); |
1844 ASSERT(bound_error.IsNull()); | 1848 ASSERT(bound_error.IsNull()); |
1845 ASSERT(!param_bound.IsInstantiated()); | 1849 ASSERT(!param_bound.IsInstantiated()); |
1846 param.set_bound(param_bound); | 1850 param.set_bound(param_bound); |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2380 } | 2384 } |
2381 // Finalize type parameters before finalizing the super type. | 2385 // Finalize type parameters before finalizing the super type. |
2382 FinalizeTypeParameters(cls); // May change super type. | 2386 FinalizeTypeParameters(cls); // May change super type. |
2383 super_class = cls.SuperClass(); | 2387 super_class = cls.SuperClass(); |
2384 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); | 2388 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); |
2385 // Only resolving rather than finalizing the upper bounds here would result in | 2389 // Only resolving rather than finalizing the upper bounds here would result in |
2386 // instantiated type parameters of the super type to temporarily have | 2390 // instantiated type parameters of the super type to temporarily have |
2387 // unfinalized bounds. It is more efficient to finalize them early. | 2391 // unfinalized bounds. It is more efficient to finalize them early. |
2388 // Finalize bounds even if running in production mode, so that a snapshot | 2392 // Finalize bounds even if running in production mode, so that a snapshot |
2389 // contains them. | 2393 // contains them. |
2390 FinalizeUpperBounds(cls, kCanonicalizeWellFormed); | 2394 FinalizeUpperBounds(cls); |
2391 // Finalize super type. | 2395 // Finalize super type. |
2392 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 2396 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
2393 if (!super_type.IsNull()) { | 2397 if (!super_type.IsNull()) { |
2394 // In case of a bound error in the super type in production mode, the | 2398 // In case of a bound error in the super type in production mode, the |
2395 // finalized super type will have a BoundedType as type argument for the | 2399 // finalized super type will have a BoundedType as type argument for the |
2396 // out of bound type argument. | 2400 // out of bound type argument. |
2397 // It should not be a problem if the class is written to a snapshot and | 2401 // It should not be a problem if the class is written to a snapshot and |
2398 // later executed in checked mode. Note that the finalized type argument | 2402 // later executed in checked mode. Note that the finalized type argument |
2399 // vector of any type of the base class will contain a BoundedType for the | 2403 // vector of any type of the base class will contain a BoundedType for the |
2400 // out of bound type argument. | 2404 // out of bound type argument. |
2401 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); | 2405 super_type = FinalizeType(cls, super_type); |
2402 cls.set_super_type(super_type); | 2406 cls.set_super_type(super_type); |
2403 } | 2407 } |
2404 // Finalize mixin type. | 2408 // Finalize mixin type. |
2405 Type& mixin_type = Type::Handle(cls.mixin()); | 2409 Type& mixin_type = Type::Handle(cls.mixin()); |
2406 if (!mixin_type.IsNull()) { | 2410 if (!mixin_type.IsNull()) { |
2407 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); | 2411 mixin_type ^= FinalizeType(cls, mixin_type); |
2408 cls.set_mixin(mixin_type); | 2412 cls.set_mixin(mixin_type); |
2409 } | 2413 } |
2410 if (cls.IsTypedefClass()) { | 2414 if (cls.IsTypedefClass()) { |
2411 Function& signature = Function::Handle(cls.signature_function()); | 2415 Function& signature = Function::Handle(cls.signature_function()); |
2412 Type& type = Type::Handle(signature.SignatureType()); | 2416 Type& type = Type::Handle(signature.SignatureType()); |
2413 ASSERT(type.signature() == signature.raw()); | 2417 ASSERT(type.signature() == signature.raw()); |
2414 | 2418 |
2415 // Check for illegal self references. | 2419 // Check for illegal self references. |
2416 GrowableArray<intptr_t> visited_aliases; | 2420 GrowableArray<intptr_t> visited_aliases; |
2417 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { | 2421 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { |
2418 const String& name = String::Handle(cls.Name()); | 2422 const String& name = String::Handle(cls.Name()); |
2419 ReportError(cls, cls.token_pos(), | 2423 ReportError(cls, cls.token_pos(), |
2420 "typedef '%s' illegally refers to itself", name.ToCString()); | 2424 "typedef '%s' illegally refers to itself", name.ToCString()); |
2421 } | 2425 } |
2422 cls.set_is_type_finalized(); | 2426 cls.set_is_type_finalized(); |
2423 | 2427 |
2424 // Resolve and finalize the result and parameter types of the signature | 2428 // Resolve and finalize the result and parameter types of the signature |
2425 // function of this typedef class. | 2429 // function of this typedef class. |
2426 FinalizeSignature(cls, signature); // Does not modify signature type. | 2430 FinalizeSignature(cls, signature); // Does not modify signature type. |
2427 ASSERT(signature.SignatureType() == type.raw()); | 2431 ASSERT(signature.SignatureType() == type.raw()); |
2428 | 2432 |
2429 // Resolve and finalize the signature type of this typedef. | 2433 // Resolve and finalize the signature type of this typedef. |
2430 type ^= FinalizeType(cls, type, kCanonicalizeWellFormed); | 2434 type ^= FinalizeType(cls, type); |
2431 | 2435 |
2432 // If a different canonical signature type is returned, update the signature | 2436 // If a different canonical signature type is returned, update the signature |
2433 // function of the typedef. | 2437 // function of the typedef. |
2434 signature = type.signature(); | 2438 signature = type.signature(); |
2435 signature.SetSignatureType(type); | 2439 signature.SetSignatureType(type); |
2436 cls.set_signature_function(signature); | 2440 cls.set_signature_function(signature); |
2437 | 2441 |
2438 // Closure instances do not refer to this typedef as their class, so there | 2442 // Closure instances do not refer to this typedef as their class, so there |
2439 // is no need to add this typedef class to the subclasses of _Closure. | 2443 // is no need to add this typedef class to the subclasses of _Closure. |
2440 ASSERT(super_type.IsNull() || super_type.IsObjectType()); | 2444 ASSERT(super_type.IsNull() || super_type.IsObjectType()); |
2441 | 2445 |
2442 return; | 2446 return; |
2443 } | 2447 } |
2444 | 2448 |
2445 // Finalize interface types (but not necessarily interface classes). | 2449 // Finalize interface types (but not necessarily interface classes). |
2446 Array& interface_types = Array::Handle(cls.interfaces()); | 2450 Array& interface_types = Array::Handle(cls.interfaces()); |
2447 AbstractType& interface_type = AbstractType::Handle(); | 2451 AbstractType& interface_type = AbstractType::Handle(); |
2448 AbstractType& seen_interf = AbstractType::Handle(); | 2452 AbstractType& seen_interf = AbstractType::Handle(); |
2449 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 2453 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
2450 interface_type ^= interface_types.At(i); | 2454 interface_type ^= interface_types.At(i); |
2451 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); | 2455 interface_type = FinalizeType(cls, interface_type); |
2452 interface_types.SetAt(i, interface_type); | 2456 interface_types.SetAt(i, interface_type); |
2453 | 2457 |
2454 // Check whether the interface is duplicated. We need to wait with | 2458 // Check whether the interface is duplicated. We need to wait with |
2455 // this check until the super type and interface types are finalized, | 2459 // this check until the super type and interface types are finalized, |
2456 // so that we can use Type::Equals() for the test. | 2460 // so that we can use Type::Equals() for the test. |
2457 // TODO(regis): This restriction about duplicated interfaces may get lifted. | 2461 // TODO(regis): This restriction about duplicated interfaces may get lifted. |
2458 ASSERT(interface_type.IsFinalized()); | 2462 ASSERT(interface_type.IsFinalized()); |
2459 ASSERT(super_type.IsNull() || super_type.IsFinalized()); | 2463 ASSERT(super_type.IsNull() || super_type.IsFinalized()); |
2460 if (!super_type.IsNull() && interface_type.Equals(super_type)) { | 2464 if (!super_type.IsNull() && interface_type.Equals(super_type)) { |
2461 ReportError(cls, cls.token_pos(), | 2465 ReportError(cls, cls.token_pos(), |
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3708 ProgramVisitor::VisitFunctions(&function_visitor); | 3712 ProgramVisitor::VisitFunctions(&function_visitor); |
3709 | 3713 |
3710 class ClearCodeClassVisitor : public ClassVisitor { | 3714 class ClearCodeClassVisitor : public ClassVisitor { |
3711 void Visit(const Class& cls) { cls.DisableAllocationStub(); } | 3715 void Visit(const Class& cls) { cls.DisableAllocationStub(); } |
3712 }; | 3716 }; |
3713 ClearCodeClassVisitor class_visitor; | 3717 ClearCodeClassVisitor class_visitor; |
3714 ProgramVisitor::VisitClasses(&class_visitor); | 3718 ProgramVisitor::VisitClasses(&class_visitor); |
3715 } | 3719 } |
3716 | 3720 |
3717 } // namespace dart | 3721 } // namespace dart |
OLD | NEW |