| 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/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 const GrowableObjectArray& pending_classes, | 90 const GrowableObjectArray& pending_classes, |
| 91 GrowableArray<intptr_t>* finalized_super_classes) { | 91 GrowableArray<intptr_t>* finalized_super_classes) { |
| 92 Class& cls = Class::Handle(); | 92 Class& cls = Class::Handle(); |
| 93 AbstractType& super_type = Type::Handle(); | 93 AbstractType& super_type = Type::Handle(); |
| 94 for (intptr_t i = 0; i < pending_classes.Length(); i++) { | 94 for (intptr_t i = 0; i < pending_classes.Length(); i++) { |
| 95 cls ^= pending_classes.At(i); | 95 cls ^= pending_classes.At(i); |
| 96 ASSERT(!cls.is_finalized()); | 96 ASSERT(!cls.is_finalized()); |
| 97 super_type = cls.super_type(); | 97 super_type = cls.super_type(); |
| 98 if (!super_type.IsNull()) { | 98 if (!super_type.IsNull()) { |
| 99 if (!super_type.IsMalformed() && | 99 if (!super_type.IsMalformed() && |
| 100 super_type.HasResolvedTypeClass() && | 100 super_type.HasResolvedTypeClass()) { |
| 101 Class::Handle(super_type.type_class()).is_finalized()) { | 101 cls ^= super_type.type_class(); |
| 102 AddSuperType(super_type, finalized_super_classes); | 102 if (cls.is_finalized()) { |
| 103 AddSuperType(super_type, finalized_super_classes); |
| 104 } |
| 103 } | 105 } |
| 104 } | 106 } |
| 105 } | 107 } |
| 106 } | 108 } |
| 107 | 109 |
| 108 | 110 |
| 109 // Class finalization occurs: | 111 // Class finalization occurs: |
| 110 // a) when bootstrap process completes (VerifyBootstrapClasses). | 112 // a) when bootstrap process completes (VerifyBootstrapClasses). |
| 111 // b) after the user classes are loaded (dart_api). | 113 // b) after the user classes are loaded (dart_api). |
| 112 bool ClassFinalizer::FinalizePendingClasses() { | 114 bool ClassFinalizer::FinalizePendingClasses() { |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 const Script& script = Script::Handle(cls.script()); | 369 const Script& script = Script::Handle(cls.script()); |
| 368 ReportError(script, factory.token_pos(), | 370 ReportError(script, factory.token_pos(), |
| 369 "constructor '%s' must be const as required by redirecting" | 371 "constructor '%s' must be const as required by redirecting" |
| 370 "const factory '%s'", | 372 "const factory '%s'", |
| 371 String::Handle(target.name()).ToCString(), | 373 String::Handle(target.name()).ToCString(), |
| 372 String::Handle(factory.name()).ToCString()); | 374 String::Handle(factory.name()).ToCString()); |
| 373 } | 375 } |
| 374 | 376 |
| 375 // Update redirection data with resolved target. | 377 // Update redirection data with resolved target. |
| 376 factory.SetRedirectionTarget(target); | 378 factory.SetRedirectionTarget(target); |
| 377 factory.SetRedirectionIdentifier(String::Handle()); // Not needed anymore. | 379 // Not needed anymore. |
| 380 factory.SetRedirectionIdentifier(String::null_object()); |
| 378 if (!target.IsRedirectingFactory()) { | 381 if (!target.IsRedirectingFactory()) { |
| 379 return; | 382 return; |
| 380 } | 383 } |
| 381 | 384 |
| 382 // The target is itself a redirecting factory. Recursively resolve its own | 385 // The target is itself a redirecting factory. Recursively resolve its own |
| 383 // target and update the current redirection data to point to the end target | 386 // target and update the current redirection data to point to the end target |
| 384 // of the redirection chain. | 387 // of the redirection chain. |
| 385 ResolveRedirectingFactoryTarget(target_class, target, visited_factories); | 388 ResolveRedirectingFactoryTarget(target_class, target, visited_factories); |
| 386 Type& target_type = Type::Handle(target.RedirectionType()); | 389 Type& target_type = Type::Handle(target.RedirectionType()); |
| 387 Function& target_target = Function::Handle(target.RedirectionTarget()); | 390 Function& target_target = Function::Handle(target.RedirectionTarget()); |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 parameterized_type.UserVisibleName()); | 878 parameterized_type.UserVisibleName()); |
| 876 const Type& malformed_bound = Type::Handle( | 879 const Type& malformed_bound = Type::Handle( |
| 877 NewFinalizedMalformedType(bound_error, | 880 NewFinalizedMalformedType(bound_error, |
| 878 cls, | 881 cls, |
| 879 parameterized_type.token_pos(), | 882 parameterized_type.token_pos(), |
| 880 bound_finalization, | 883 bound_finalization, |
| 881 "type '%s' has an out of bound type argument", | 884 "type '%s' has an out of bound type argument", |
| 882 parameterized_type_name.ToCString())); | 885 parameterized_type_name.ToCString())); |
| 883 return BoundedType::New(parameterized_type, | 886 return BoundedType::New(parameterized_type, |
| 884 malformed_bound, | 887 malformed_bound, |
| 885 TypeParameter::Handle()); | 888 TypeParameter::null_object()); |
| 886 } | 889 } |
| 887 | 890 |
| 888 if (finalization >= kCanonicalize) { | 891 if (finalization >= kCanonicalize) { |
| 889 return parameterized_type.Canonicalize(); | 892 return parameterized_type.Canonicalize(); |
| 890 } else { | 893 } else { |
| 891 return parameterized_type.raw(); | 894 return parameterized_type.raw(); |
| 892 } | 895 } |
| 893 } | 896 } |
| 894 | 897 |
| 895 | 898 |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 ResolveAndFinalizeSignature(cls, sig_function); | 1434 ResolveAndFinalizeSignature(cls, sig_function); |
| 1432 | 1435 |
| 1433 // Resolve and finalize the signature type of this signature class. | 1436 // Resolve and finalize the signature type of this signature class. |
| 1434 const Type& sig_type = Type::Handle(cls.SignatureType()); | 1437 const Type& sig_type = Type::Handle(cls.SignatureType()); |
| 1435 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); | 1438 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); |
| 1436 return; | 1439 return; |
| 1437 } | 1440 } |
| 1438 // Finalize interface types (but not necessarily interface classes). | 1441 // Finalize interface types (but not necessarily interface classes). |
| 1439 Array& interface_types = Array::Handle(cls.interfaces()); | 1442 Array& interface_types = Array::Handle(cls.interfaces()); |
| 1440 AbstractType& interface_type = AbstractType::Handle(); | 1443 AbstractType& interface_type = AbstractType::Handle(); |
| 1444 AbstractType& seen_interf = AbstractType::Handle(); |
| 1441 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 1445 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 1442 interface_type ^= interface_types.At(i); | 1446 interface_type ^= interface_types.At(i); |
| 1443 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); | 1447 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); |
| 1444 interface_types.SetAt(i, interface_type); | 1448 interface_types.SetAt(i, interface_type); |
| 1445 | 1449 |
| 1446 // Check whether the interface is duplicated. We need to wait with | 1450 // Check whether the interface is duplicated. We need to wait with |
| 1447 // this check until the super type and interface types are finalized, | 1451 // this check until the super type and interface types are finalized, |
| 1448 // so that we can use Type::Equals() for the test. | 1452 // so that we can use Type::Equals() for the test. |
| 1449 ASSERT(interface_type.IsFinalized()); | 1453 ASSERT(interface_type.IsFinalized()); |
| 1450 ASSERT(super_type.IsNull() || super_type.IsFinalized()); | 1454 ASSERT(super_type.IsNull() || super_type.IsFinalized()); |
| 1451 if (!super_type.IsNull() && interface_type.Equals(super_type)) { | 1455 if (!super_type.IsNull() && interface_type.Equals(super_type)) { |
| 1452 const Script& script = Script::Handle(cls.script()); | 1456 const Script& script = Script::Handle(cls.script()); |
| 1453 ReportError(script, cls.token_pos(), | 1457 ReportError(script, cls.token_pos(), |
| 1454 "super type '%s' may not be listed in " | 1458 "super type '%s' may not be listed in " |
| 1455 "implements clause of class '%s'", | 1459 "implements clause of class '%s'", |
| 1456 String::Handle(super_type.Name()).ToCString(), | 1460 String::Handle(super_type.Name()).ToCString(), |
| 1457 String::Handle(cls.Name()).ToCString()); | 1461 String::Handle(cls.Name()).ToCString()); |
| 1458 } | 1462 } |
| 1459 AbstractType& seen_interf = AbstractType::Handle(); | |
| 1460 for (intptr_t j = 0; j < i; j++) { | 1463 for (intptr_t j = 0; j < i; j++) { |
| 1461 seen_interf ^= interface_types.At(j); | 1464 seen_interf ^= interface_types.At(j); |
| 1462 if (interface_type.Equals(seen_interf)) { | 1465 if (interface_type.Equals(seen_interf)) { |
| 1463 const Script& script = Script::Handle(cls.script()); | 1466 const Script& script = Script::Handle(cls.script()); |
| 1464 ReportError(script, cls.token_pos(), | 1467 ReportError(script, cls.token_pos(), |
| 1465 "interface '%s' appears twice in " | 1468 "interface '%s' appears twice in " |
| 1466 "implements clause of class '%s'", | 1469 "implements clause of class '%s'", |
| 1467 String::Handle(interface_type.Name()).ToCString(), | 1470 String::Handle(interface_type.Name()).ToCString(), |
| 1468 String::Handle(cls.Name()).ToCString()); | 1471 String::Handle(cls.Name()).ToCString()); |
| 1469 } | 1472 } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1616 // Resolve super type and all mixin types. | 1619 // Resolve super type and all mixin types. |
| 1617 const GrowableObjectArray& type_args = | 1620 const GrowableObjectArray& type_args = |
| 1618 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1621 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 1619 AbstractType& type = AbstractType::Handle(mixin_app.super_type()); | 1622 AbstractType& type = AbstractType::Handle(mixin_app.super_type()); |
| 1620 ResolveType(cls, type, kCanonicalizeWellFormed); | 1623 ResolveType(cls, type, kCanonicalizeWellFormed); |
| 1621 ASSERT(type.HasResolvedTypeClass()); | 1624 ASSERT(type.HasResolvedTypeClass()); |
| 1622 // TODO(hausner): May need to handle BoundedType here. | 1625 // TODO(hausner): May need to handle BoundedType here. |
| 1623 ASSERT(type.IsType()); | 1626 ASSERT(type.IsType()); |
| 1624 CollectTypeArguments(cls, Type::Cast(type), type_args); | 1627 CollectTypeArguments(cls, Type::Cast(type), type_args); |
| 1625 const Array& mixins = Array::Handle(mixin_app.mixin_types()); | 1628 const Array& mixins = Array::Handle(mixin_app.mixin_types()); |
| 1629 Class& mixin_app_class = Class::Handle(); |
| 1626 for (int i = 0; i < mixins.Length(); i++) { | 1630 for (int i = 0; i < mixins.Length(); i++) { |
| 1627 type ^= mixins.At(i); | 1631 type ^= mixins.At(i); |
| 1628 ASSERT(type.HasResolvedTypeClass()); // Newly created class in parser. | 1632 ASSERT(type.HasResolvedTypeClass()); // Newly created class in parser. |
| 1629 const Class& mixin_app_class = Class::Handle(type.type_class()); | 1633 mixin_app_class ^= type.type_class(); |
| 1630 type = mixin_app_class.mixin(); | 1634 type = mixin_app_class.mixin(); |
| 1631 ASSERT(!type.IsNull()); | 1635 ASSERT(!type.IsNull()); |
| 1632 ResolveType(cls, type, kCanonicalizeWellFormed); | 1636 ResolveType(cls, type, kCanonicalizeWellFormed); |
| 1633 ASSERT(type.HasResolvedTypeClass()); | 1637 ASSERT(type.HasResolvedTypeClass()); |
| 1634 ASSERT(type.IsType()); | 1638 ASSERT(type.IsType()); |
| 1635 CollectTypeArguments(cls, Type::Cast(type), type_args); | 1639 CollectTypeArguments(cls, Type::Cast(type), type_args); |
| 1636 } | 1640 } |
| 1637 const TypeArguments& mixin_app_args = | 1641 const TypeArguments& mixin_app_args = |
| 1638 TypeArguments::Handle(TypeArguments::New(type_args.Length())); | 1642 TypeArguments::Handle(TypeArguments::New(type_args.Length())); |
| 1639 for (int i = 0; i < type_args.Length(); i++) { | 1643 for (int i = 0; i < type_args.Length(); i++) { |
| 1640 type ^= type_args.At(i); | 1644 type ^= type_args.At(i); |
| 1641 mixin_app_args.SetTypeAt(i, type); | 1645 mixin_app_args.SetTypeAt(i, type); |
| 1642 } | 1646 } |
| 1643 if (FLAG_trace_class_finalization) { | 1647 if (FLAG_trace_class_finalization) { |
| 1644 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", | 1648 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", |
| 1645 mixin_app_args.ToCString()); | 1649 mixin_app_args.ToCString()); |
| 1646 } | 1650 } |
| 1647 // The last element in the mixins array is the lowest mixin application | 1651 // The last element in the mixins array is the lowest mixin application |
| 1648 // type in the mixin chain. Build a new super type with its type class | 1652 // type in the mixin chain. Build a new super type with its type class |
| 1649 // and the collected type arguments from the super type and all | 1653 // and the collected type arguments from the super type and all |
| 1650 // mixin types. This super type replaces the MixinAppType object | 1654 // mixin types. This super type replaces the MixinAppType object |
| 1651 // in the class that extends the mixin application. | 1655 // in the class that extends the mixin application. |
| 1652 type ^= mixins.At(mixins.Length() - 1); | 1656 type ^= mixins.At(mixins.Length() - 1); |
| 1653 const Class& resolved_mixin_app_class = Class::Handle(type.type_class()); | 1657 mixin_app_class ^= type.type_class(); |
| 1654 Type& resolved_mixin_app_type = Type::Handle(); | 1658 return Type::New(mixin_app_class, |
| 1655 resolved_mixin_app_type = Type::New(resolved_mixin_app_class, | 1659 mixin_app_args, |
| 1656 mixin_app_args, | 1660 mixin_app.token_pos()); |
| 1657 mixin_app.token_pos()); | |
| 1658 return resolved_mixin_app_type.raw(); | |
| 1659 } | 1661 } |
| 1660 | 1662 |
| 1661 | 1663 |
| 1662 // Recursively walks the graph of explicitly declared super type and | 1664 // Recursively walks the graph of explicitly declared super type and |
| 1663 // interfaces, resolving unresolved super types and interfaces. | 1665 // interfaces, resolving unresolved super types and interfaces. |
| 1664 // Reports an error if there is an interface reference that cannot be | 1666 // Reports an error if there is an interface reference that cannot be |
| 1665 // resolved, or if there is a cycle in the graph. We detect cycles by | 1667 // resolved, or if there is a cycle in the graph. We detect cycles by |
| 1666 // remembering interfaces we've visited in each path through the | 1668 // remembering interfaces we've visited in each path through the |
| 1667 // graph. If we visit an interface a second time on a given path, | 1669 // graph. If we visit an interface a second time on a given path, |
| 1668 // we found a loop. | 1670 // we found a loop. |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1908 } | 1910 } |
| 1909 } | 1911 } |
| 1910 // In checked mode, always mark the type as malformed. | 1912 // In checked mode, always mark the type as malformed. |
| 1911 // In production mode, mark the type as malformed only if its type class is | 1913 // In production mode, mark the type as malformed only if its type class is |
| 1912 // not resolved. | 1914 // not resolved. |
| 1913 // In both mode, make the type raw, since it may not be possible to | 1915 // In both mode, make the type raw, since it may not be possible to |
| 1914 // properly finalize its type arguments. | 1916 // properly finalize its type arguments. |
| 1915 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { | 1917 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { |
| 1916 type.set_malformed_error(error); | 1918 type.set_malformed_error(error); |
| 1917 } | 1919 } |
| 1918 type.set_arguments(AbstractTypeArguments::Handle()); | 1920 type.set_arguments(AbstractTypeArguments::null_object()); |
| 1919 if (!type.IsFinalized()) { | 1921 if (!type.IsFinalized()) { |
| 1920 type.SetIsFinalized(); | 1922 type.SetIsFinalized(); |
| 1921 // Do not canonicalize malformed types, since they may not be resolved. | 1923 // Do not canonicalize malformed types, since they may not be resolved. |
| 1922 } else { | 1924 } else { |
| 1923 // The only case where the malformed type was already finalized is when its | 1925 // The only case where the malformed type was already finalized is when its |
| 1924 // type arguments are not within bounds. In that case, we have a prev_error. | 1926 // type arguments are not within bounds. In that case, we have a prev_error. |
| 1925 ASSERT(!prev_error.IsNull()); | 1927 ASSERT(!prev_error.IsNull()); |
| 1926 } | 1928 } |
| 1927 } | 1929 } |
| 1928 | 1930 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2042 expected_name ^= String::New("_offset"); | 2044 expected_name ^= String::New("_offset"); |
| 2043 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2045 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2044 field ^= fields_array.At(2); | 2046 field ^= fields_array.At(2); |
| 2045 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2047 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2046 name ^= field.name(); | 2048 name ^= field.name(); |
| 2047 ASSERT(name.Equals("length")); | 2049 ASSERT(name.Equals("length")); |
| 2048 #endif | 2050 #endif |
| 2049 } | 2051 } |
| 2050 | 2052 |
| 2051 } // namespace dart | 2053 } // namespace dart |
| OLD | NEW |