| 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 |