| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 1721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1732 return raw() == Type::Handle(Type::ObjectType()).type_class(); | 1732 return raw() == Type::Handle(Type::ObjectType()).type_class(); |
| 1733 } | 1733 } |
| 1734 | 1734 |
| 1735 | 1735 |
| 1736 bool Class::IsCanonicalSignatureClass() const { | 1736 bool Class::IsCanonicalSignatureClass() const { |
| 1737 const Function& function = Function::Handle(signature_function()); | 1737 const Function& function = Function::Handle(signature_function()); |
| 1738 return (!function.IsNull() && (function.signature_class() == raw())); | 1738 return (!function.IsNull() && (function.signature_class() == raw())); |
| 1739 } | 1739 } |
| 1740 | 1740 |
| 1741 | 1741 |
| 1742 // Checks if the type S is a subtype of type T. | 1742 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. |
| 1743 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. |
| 1743 // Type S is specified by this class parameterized with 'type_arguments', and | 1744 // Type S is specified by this class parameterized with 'type_arguments', and |
| 1744 // type T by class 'other' parameterized with 'other_type_arguments'. | 1745 // type T by class 'other' parameterized with 'other_type_arguments'. |
| 1745 // This class and class 'other' do not need to be finalized, however, they must | 1746 // This class and class 'other' do not need to be finalized, however, they must |
| 1746 // be resolved as well as their interfaces. | 1747 // be resolved as well as their interfaces. |
| 1747 bool Class::IsSubtypeOf( | 1748 bool Class::TypeTest( |
| 1749 TypeTestKind test_kind, |
| 1748 const AbstractTypeArguments& type_arguments, | 1750 const AbstractTypeArguments& type_arguments, |
| 1749 const Class& other, | 1751 const Class& other, |
| 1750 const AbstractTypeArguments& other_type_arguments, | 1752 const AbstractTypeArguments& other_type_arguments, |
| 1751 Error* malformed_error) const { | 1753 Error* malformed_error) const { |
| 1752 // Check for DynamicType. | 1754 // Check for DynamicType. |
| 1753 // The DynamicType on the lefthand side is replaced by the bottom type, which | 1755 // Each occurrence of DynamicType in type T is interpreted as the Dynamic |
| 1754 // is more specific than any type. | 1756 // type, a supertype of all types. |
| 1755 // Any type is more specific than the DynamicType on the righthand side. | 1757 if (other.IsDynamicClass()) { |
| 1756 if (IsDynamicClass() || other.IsDynamicClass()) { | |
| 1757 return true; | 1758 return true; |
| 1758 } | 1759 } |
| 1760 // In the case of a subtype test, each occurrence of DynamicType in type S is |
| 1761 // interpreted as the bottom type, a subtype of all types. |
| 1762 if (IsDynamicClass()) { |
| 1763 return test_kind == kIsSubtypeOf; |
| 1764 } |
| 1759 // Check for reflexivity. | 1765 // Check for reflexivity. |
| 1760 if (raw() == other.raw()) { | 1766 if (raw() == other.raw()) { |
| 1761 const intptr_t len = NumTypeArguments(); | 1767 const intptr_t len = NumTypeArguments(); |
| 1762 if (len == 0) { | 1768 if (len == 0) { |
| 1763 return true; | 1769 return true; |
| 1764 } | 1770 } |
| 1765 // Since we do not truncate the type argument vector of a subclass (see | 1771 // Since we do not truncate the type argument vector of a subclass (see |
| 1766 // below), we only check a prefix of the proper length. | 1772 // below), we only check a prefix of the proper length. |
| 1767 // Check for covariance. | 1773 // Check for covariance. |
| 1768 if (type_arguments.IsNull() || | 1774 if (other_type_arguments.IsNull() || |
| 1769 other_type_arguments.IsNull() || | |
| 1770 type_arguments.IsRawInstantiatedRaw(len) || | |
| 1771 other_type_arguments.IsRawInstantiatedRaw(len)) { | 1775 other_type_arguments.IsRawInstantiatedRaw(len)) { |
| 1772 return true; | 1776 return true; |
| 1773 } | 1777 } |
| 1774 return type_arguments.IsSubtypeOf(other_type_arguments, | 1778 if (type_arguments.IsNull() || |
| 1775 len, | 1779 type_arguments.IsRawInstantiatedRaw(len)) { |
| 1776 malformed_error); | 1780 return test_kind == kIsSubtypeOf; |
| 1781 } |
| 1782 return type_arguments.TypeTest(test_kind, |
| 1783 other_type_arguments, |
| 1784 len, |
| 1785 malformed_error); |
| 1777 } | 1786 } |
| 1787 // TODO(regis): Check for interface type S implementing method call() of |
| 1788 // function type T. |
| 1778 // Check for two function types. | 1789 // Check for two function types. |
| 1779 if (IsSignatureClass() && other.IsSignatureClass()) { | 1790 if (IsSignatureClass() && other.IsSignatureClass()) { |
| 1780 const Function& fun = Function::Handle(signature_function()); | 1791 const Function& fun = Function::Handle(signature_function()); |
| 1781 const Function& other_fun = Function::Handle(other.signature_function()); | 1792 const Function& other_fun = Function::Handle(other.signature_function()); |
| 1782 return fun.IsSubtypeOf(type_arguments, | 1793 return fun.IsSubtypeOf(type_arguments, |
| 1783 other_fun, | 1794 other_fun, |
| 1784 other_type_arguments, | 1795 other_type_arguments, |
| 1785 malformed_error); | 1796 malformed_error); |
| 1786 } | 1797 } |
| 1787 // Check for 'direct super type' in the case of an interface | 1798 // Check for 'direct super type' in the case of an interface |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1813 // check from true in production mode to false in checked mode. | 1824 // check from true in production mode to false in checked mode. |
| 1814 if (FLAG_enable_type_checks && !interface_args.IsNull()) { | 1825 if (FLAG_enable_type_checks && !interface_args.IsNull()) { |
| 1815 // Pass type_arguments as bounds instantiator. | 1826 // Pass type_arguments as bounds instantiator. |
| 1816 if (!interface_args.IsWithinBoundsOf(interface_class, | 1827 if (!interface_args.IsWithinBoundsOf(interface_class, |
| 1817 type_arguments, | 1828 type_arguments, |
| 1818 malformed_error)) { | 1829 malformed_error)) { |
| 1819 continue; | 1830 continue; |
| 1820 } | 1831 } |
| 1821 } | 1832 } |
| 1822 } | 1833 } |
| 1823 if (interface_class.IsSubtypeOf(interface_args, | 1834 if (interface_class.TypeTest(test_kind, |
| 1824 other, | 1835 interface_args, |
| 1825 other_type_arguments, | 1836 other, |
| 1826 malformed_error)) { | 1837 other_type_arguments, |
| 1838 malformed_error)) { |
| 1827 return true; | 1839 return true; |
| 1828 } | 1840 } |
| 1829 } | 1841 } |
| 1830 // Check the interface case. | 1842 // Check the interface case. |
| 1831 if (is_interface()) { | 1843 if (is_interface()) { |
| 1832 // We already checked the case where 'other' is an interface. Now, 'this', | 1844 // We already checked the case where 'other' is an interface. Now, 'this', |
| 1833 // an interface, cannot be more specific than a class, except class Object, | 1845 // an interface, cannot be more specific than a class, except class Object, |
| 1834 // because although Object is not considered an interface by the vm, it is | 1846 // because although Object is not considered an interface by the vm, it is |
| 1835 // one. In other words, all classes implementing this interface also extend | 1847 // one. In other words, all classes implementing this interface also extend |
| 1836 // class Object. An interface is also more specific than the DynamicType. | 1848 // class Object. An interface is also more specific than the DynamicType. |
| 1837 return (other.IsDynamicClass() || other.IsObjectClass()); | 1849 return (other.IsDynamicClass() || other.IsObjectClass()); |
| 1838 } | 1850 } |
| 1839 const Class& super_class = Class::Handle(SuperClass()); | 1851 const Class& super_class = Class::Handle(SuperClass()); |
| 1840 if (super_class.IsNull()) { | 1852 if (super_class.IsNull()) { |
| 1841 return false; | 1853 return false; |
| 1842 } | 1854 } |
| 1843 // Instead of truncating the type argument vector to the length of the super | 1855 // Instead of truncating the type argument vector to the length of the super |
| 1844 // type argument vector, we make sure that the code works with a vector that | 1856 // type argument vector, we make sure that the code works with a vector that |
| 1845 // is longer than necessary. | 1857 // is longer than necessary. |
| 1846 return super_class.IsSubtypeOf(type_arguments, | 1858 return super_class.TypeTest(test_kind, |
| 1847 other, | 1859 type_arguments, |
| 1848 other_type_arguments, | 1860 other, |
| 1849 malformed_error); | 1861 other_type_arguments, |
| 1862 malformed_error); |
| 1850 } | 1863 } |
| 1851 | 1864 |
| 1852 | 1865 |
| 1853 bool Class::IsTopLevel() const { | 1866 bool Class::IsTopLevel() const { |
| 1854 return String::Handle(Name()).Equals("::"); | 1867 return String::Handle(Name()).Equals("::"); |
| 1855 } | 1868 } |
| 1856 | 1869 |
| 1857 | 1870 |
| 1858 RawFunction* Class::LookupDynamicFunction(const String& name) const { | 1871 RawFunction* Class::LookupDynamicFunction(const String& name) const { |
| 1859 Function& function = Function::Handle(LookupFunction(name)); | 1872 Function& function = Function::Handle(LookupFunction(name)); |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2396 (type_class() == Type::Handle(Type::FunctionInterface()).type_class()); | 2409 (type_class() == Type::Handle(Type::FunctionInterface()).type_class()); |
| 2397 } | 2410 } |
| 2398 | 2411 |
| 2399 | 2412 |
| 2400 bool AbstractType::IsListInterface() const { | 2413 bool AbstractType::IsListInterface() const { |
| 2401 return HasResolvedTypeClass() && | 2414 return HasResolvedTypeClass() && |
| 2402 (type_class() == Type::Handle(Type::ListInterface()).type_class()); | 2415 (type_class() == Type::Handle(Type::ListInterface()).type_class()); |
| 2403 } | 2416 } |
| 2404 | 2417 |
| 2405 | 2418 |
| 2406 bool AbstractType::IsSubtypeOf(const AbstractType& other, | 2419 bool AbstractType::TypeTest(TypeTestKind test_kind, |
| 2407 Error* malformed_error) const { | 2420 const AbstractType& other, |
| 2421 Error* malformed_error) const { |
| 2408 ASSERT(IsFinalized()); | 2422 ASSERT(IsFinalized()); |
| 2409 ASSERT(other.IsFinalized()); | 2423 ASSERT(other.IsFinalized()); |
| 2410 // In case the type checked in a type test is malformed, the code generator | 2424 // In case the type checked in a type test is malformed, the code generator |
| 2411 // may compile a throw instead of a run time call performing the type check. | 2425 // may compile a throw instead of a run time call performing the type check. |
| 2412 // However, in checked mode, a function type may include malformed result type | 2426 // However, in checked mode, a function type may include malformed result type |
| 2413 // and/or malformed parameter types, which will then be encountered here at | 2427 // and/or malformed parameter types, which will then be encountered here at |
| 2414 // run time. | 2428 // run time. |
| 2415 if (IsMalformed()) { | 2429 if (IsMalformed()) { |
| 2416 ASSERT(FLAG_enable_type_checks); | 2430 ASSERT(FLAG_enable_type_checks); |
| 2417 if (malformed_error->IsNull()) { | 2431 if (malformed_error->IsNull()) { |
| 2418 *malformed_error = this->malformed_error(); | 2432 *malformed_error = this->malformed_error(); |
| 2419 } | 2433 } |
| 2420 return false; | 2434 return false; |
| 2421 } | 2435 } |
| 2422 if (other.IsMalformed()) { | 2436 if (other.IsMalformed()) { |
| 2423 ASSERT(FLAG_enable_type_checks); | 2437 ASSERT(FLAG_enable_type_checks); |
| 2424 if (malformed_error->IsNull()) { | 2438 if (malformed_error->IsNull()) { |
| 2425 *malformed_error = other.malformed_error(); | 2439 *malformed_error = other.malformed_error(); |
| 2426 } | 2440 } |
| 2427 return false; | 2441 return false; |
| 2428 } | 2442 } |
| 2429 // AbstractType parameters cannot be handled by Class::IsSubtypeOf(). | 2443 // AbstractType parameters cannot be handled by Class::TypeTest(). |
| 2430 // When comparing two uninstantiated function types, one returning type | 2444 // When comparing two uninstantiated function types, one returning type |
| 2431 // parameter K, the other returning type parameter V, we cannot assume that K | 2445 // parameter K, the other returning type parameter V, we cannot assume that K |
| 2432 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if | 2446 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if |
| 2433 // they have the same index (both are finalized, so their indices are | 2447 // they have the same index (both are finalized, so their indices are |
| 2434 // comparable). | 2448 // comparable). |
| 2435 // The same rule applies When checking the upper bound of a still | 2449 // The same rule applies When checking the upper bound of a still |
| 2436 // uninstantiated type at compile time. Returning false will defer the test | 2450 // uninstantiated type at compile time. Returning false will defer the test |
| 2437 // to run time. But there are cases where it can be decided at compile time. | 2451 // to run time. But there are cases where it can be decided at compile time. |
| 2438 // For example, with class A<K, V extends K>, new A<T, T> called from within | 2452 // For example, with class A<K, V extends K>, new A<T, T> called from within |
| 2439 // a class B<T> will never require a run time bounds check, even it T is | 2453 // a class B<T> will never require a run time bounds check, even it T is |
| 2440 // uninstantiated at compile time. | 2454 // uninstantiated at compile time. |
| 2441 if (IsTypeParameter() || other.IsTypeParameter()) { | 2455 if (IsTypeParameter()) { |
| 2442 return IsTypeParameter() && other.IsTypeParameter() && | 2456 if (other.IsTypeParameter()) { |
| 2443 (Index() == other.Index()); | 2457 return Index() == other.Index(); |
| 2458 } else { |
| 2459 // TODO(regis): In checked mode, if the other type is the upper bound of |
| 2460 // this type parameter, then return true. |
| 2461 // We would need to keep the upper bound associated to the type parameter. |
| 2462 } |
| 2463 return false; |
| 2464 } |
| 2465 if (other.IsTypeParameter()) { |
| 2466 return false; |
| 2444 } | 2467 } |
| 2445 const Class& cls = Class::Handle(type_class()); | 2468 const Class& cls = Class::Handle(type_class()); |
| 2446 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()), | 2469 return cls.TypeTest(test_kind, |
| 2447 Class::Handle(other.type_class()), | 2470 AbstractTypeArguments::Handle(arguments()), |
| 2448 AbstractTypeArguments::Handle(other.arguments()), | 2471 Class::Handle(other.type_class()), |
| 2449 malformed_error); | 2472 AbstractTypeArguments::Handle(other.arguments()), |
| 2473 malformed_error); |
| 2450 } | 2474 } |
| 2451 | 2475 |
| 2452 | 2476 |
| 2453 const char* AbstractType::ToCString() const { | 2477 const char* AbstractType::ToCString() const { |
| 2454 // AbstractType is an abstract class. | 2478 // AbstractType is an abstract class. |
| 2455 UNREACHABLE(); | 2479 UNREACHABLE(); |
| 2456 return "AbstractType"; | 2480 return "AbstractType"; |
| 2457 } | 2481 } |
| 2458 | 2482 |
| 2459 | 2483 |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3174 } | 3198 } |
| 3175 const Class& super_class = Class::Handle(cls.SuperClass()); | 3199 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 3176 if (!super_class.IsNull() && | 3200 if (!super_class.IsNull() && |
| 3177 !IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) { | 3201 !IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) { |
| 3178 return false; | 3202 return false; |
| 3179 } | 3203 } |
| 3180 return true; | 3204 return true; |
| 3181 } | 3205 } |
| 3182 | 3206 |
| 3183 | 3207 |
| 3184 bool AbstractTypeArguments::IsSubtypeOf( | 3208 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, |
| 3185 const AbstractTypeArguments& other, | 3209 const AbstractTypeArguments& other, |
| 3186 intptr_t len, | 3210 intptr_t len, |
| 3187 Error* malformed_error) const { | 3211 Error* malformed_error) const { |
| 3188 ASSERT(Length() >= len); | 3212 ASSERT(Length() >= len); |
| 3189 ASSERT(!other.IsNull()); | 3213 ASSERT(!other.IsNull()); |
| 3190 ASSERT(other.Length() >= len); | 3214 ASSERT(other.Length() >= len); |
| 3191 AbstractType& type = AbstractType::Handle(); | 3215 AbstractType& type = AbstractType::Handle(); |
| 3192 AbstractType& other_type = AbstractType::Handle(); | 3216 AbstractType& other_type = AbstractType::Handle(); |
| 3193 for (intptr_t i = 0; i < len; i++) { | 3217 for (intptr_t i = 0; i < len; i++) { |
| 3194 type = TypeAt(i); | 3218 type = TypeAt(i); |
| 3195 ASSERT(!type.IsNull()); | 3219 ASSERT(!type.IsNull()); |
| 3196 other_type = other.TypeAt(i); | 3220 other_type = other.TypeAt(i); |
| 3197 ASSERT(!other_type.IsNull()); | 3221 ASSERT(!other_type.IsNull()); |
| 3198 if (!type.IsSubtypeOf(other_type, malformed_error)) { | 3222 if (!type.TypeTest(test_kind, other_type, malformed_error)) { |
| 3199 return false; | 3223 return false; |
| 3200 } | 3224 } |
| 3201 } | 3225 } |
| 3202 return true; | 3226 return true; |
| 3203 } | 3227 } |
| 3204 | 3228 |
| 3205 | 3229 |
| 3206 const char* AbstractTypeArguments::ToCString() const { | 3230 const char* AbstractTypeArguments::ToCString() const { |
| 3207 // AbstractTypeArguments is an abstract class, valid only for representing | 3231 // AbstractTypeArguments is an abstract class, valid only for representing |
| 3208 // null. | 3232 // null. |
| (...skipping 6893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10102 const String& str = String::Handle(pattern()); | 10126 const String& str = String::Handle(pattern()); |
| 10103 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10127 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 10104 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10128 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 10105 char* chars = reinterpret_cast<char*>( | 10129 char* chars = reinterpret_cast<char*>( |
| 10106 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10130 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 10107 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10131 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 10108 return chars; | 10132 return chars; |
| 10109 } | 10133 } |
| 10110 | 10134 |
| 10111 } // namespace dart | 10135 } // namespace dart |
| OLD | NEW |