Chromium Code Reviews| 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 == kIsSubtypeOf, checks if type S is a subtype of type T. |
| 1743 // If test == kIsMoreSpecificThan, checks if type 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, | |
|
srdjan
2012/06/19 20:08:21
MO, it would be more readable if you call this arg
regis
2012/06/19 20:31:47
Done.
| |
| 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 == 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 == kIsSubtypeOf; |
| 1781 } | |
| 1782 return type_arguments.TypeTest(test, | |
| 1783 other_type_arguments, | |
| 1784 len, | |
| 1785 malformed_error); | |
| 1777 } | 1786 } |
| 1778 // Check for two function types. | 1787 // Check for two function types. |
| 1779 if (IsSignatureClass() && other.IsSignatureClass()) { | 1788 if (IsSignatureClass() && other.IsSignatureClass()) { |
| 1780 const Function& fun = Function::Handle(signature_function()); | 1789 const Function& fun = Function::Handle(signature_function()); |
| 1781 const Function& other_fun = Function::Handle(other.signature_function()); | 1790 const Function& other_fun = Function::Handle(other.signature_function()); |
| 1782 return fun.IsSubtypeOf(type_arguments, | 1791 return fun.IsSubtypeOf(type_arguments, |
| 1783 other_fun, | 1792 other_fun, |
| 1784 other_type_arguments, | 1793 other_type_arguments, |
| 1785 malformed_error); | 1794 malformed_error); |
| 1786 } | 1795 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1813 // check from true in production mode to false in checked mode. | 1822 // check from true in production mode to false in checked mode. |
| 1814 if (FLAG_enable_type_checks && !interface_args.IsNull()) { | 1823 if (FLAG_enable_type_checks && !interface_args.IsNull()) { |
| 1815 // Pass type_arguments as bounds instantiator. | 1824 // Pass type_arguments as bounds instantiator. |
| 1816 if (!interface_args.IsWithinBoundsOf(interface_class, | 1825 if (!interface_args.IsWithinBoundsOf(interface_class, |
| 1817 type_arguments, | 1826 type_arguments, |
| 1818 malformed_error)) { | 1827 malformed_error)) { |
| 1819 continue; | 1828 continue; |
| 1820 } | 1829 } |
| 1821 } | 1830 } |
| 1822 } | 1831 } |
| 1823 if (interface_class.IsSubtypeOf(interface_args, | 1832 if (interface_class.TypeTest(test, |
| 1824 other, | 1833 interface_args, |
| 1825 other_type_arguments, | 1834 other, |
| 1826 malformed_error)) { | 1835 other_type_arguments, |
| 1836 malformed_error)) { | |
| 1827 return true; | 1837 return true; |
| 1828 } | 1838 } |
| 1829 } | 1839 } |
| 1830 // Check the interface case. | 1840 // Check the interface case. |
| 1831 if (is_interface()) { | 1841 if (is_interface()) { |
| 1832 // We already checked the case where 'other' is an interface. Now, 'this', | 1842 // 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, | 1843 // 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 | 1844 // 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 | 1845 // one. In other words, all classes implementing this interface also extend |
| 1836 // class Object. An interface is also more specific than the DynamicType. | 1846 // class Object. An interface is also more specific than the DynamicType. |
| 1837 return (other.IsDynamicClass() || other.IsObjectClass()); | 1847 return (other.IsDynamicClass() || other.IsObjectClass()); |
| 1838 } | 1848 } |
| 1839 const Class& super_class = Class::Handle(SuperClass()); | 1849 const Class& super_class = Class::Handle(SuperClass()); |
| 1840 if (super_class.IsNull()) { | 1850 if (super_class.IsNull()) { |
| 1841 return false; | 1851 return false; |
| 1842 } | 1852 } |
| 1843 // Instead of truncating the type argument vector to the length of the super | 1853 // 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 | 1854 // type argument vector, we make sure that the code works with a vector that |
| 1845 // is longer than necessary. | 1855 // is longer than necessary. |
| 1846 return super_class.IsSubtypeOf(type_arguments, | 1856 return super_class.TypeTest(test, |
| 1847 other, | 1857 type_arguments, |
| 1848 other_type_arguments, | 1858 other, |
| 1849 malformed_error); | 1859 other_type_arguments, |
| 1860 malformed_error); | |
| 1850 } | 1861 } |
| 1851 | 1862 |
| 1852 | 1863 |
| 1853 bool Class::IsTopLevel() const { | 1864 bool Class::IsTopLevel() const { |
| 1854 return String::Handle(Name()).Equals("::"); | 1865 return String::Handle(Name()).Equals("::"); |
| 1855 } | 1866 } |
| 1856 | 1867 |
| 1857 | 1868 |
| 1858 RawFunction* Class::LookupDynamicFunction(const String& name) const { | 1869 RawFunction* Class::LookupDynamicFunction(const String& name) const { |
| 1859 Function& function = Function::Handle(LookupFunction(name)); | 1870 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()); | 2407 (type_class() == Type::Handle(Type::FunctionInterface()).type_class()); |
| 2397 } | 2408 } |
| 2398 | 2409 |
| 2399 | 2410 |
| 2400 bool AbstractType::IsListInterface() const { | 2411 bool AbstractType::IsListInterface() const { |
| 2401 return HasResolvedTypeClass() && | 2412 return HasResolvedTypeClass() && |
| 2402 (type_class() == Type::Handle(Type::ListInterface()).type_class()); | 2413 (type_class() == Type::Handle(Type::ListInterface()).type_class()); |
| 2403 } | 2414 } |
| 2404 | 2415 |
| 2405 | 2416 |
| 2406 bool AbstractType::IsSubtypeOf(const AbstractType& other, | 2417 bool AbstractType::TypeTest(TypeTestKind test, |
| 2407 Error* malformed_error) const { | 2418 const AbstractType& other, |
| 2419 Error* malformed_error) const { | |
| 2408 ASSERT(IsFinalized()); | 2420 ASSERT(IsFinalized()); |
| 2409 ASSERT(other.IsFinalized()); | 2421 ASSERT(other.IsFinalized()); |
| 2410 // In case the type checked in a type test is malformed, the code generator | 2422 // 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. | 2423 // 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 | 2424 // 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 | 2425 // and/or malformed parameter types, which will then be encountered here at |
| 2414 // run time. | 2426 // run time. |
| 2415 if (IsMalformed()) { | 2427 if (IsMalformed()) { |
| 2416 ASSERT(FLAG_enable_type_checks); | 2428 ASSERT(FLAG_enable_type_checks); |
| 2417 if (malformed_error->IsNull()) { | 2429 if (malformed_error->IsNull()) { |
| 2418 *malformed_error = this->malformed_error(); | 2430 *malformed_error = this->malformed_error(); |
| 2419 } | 2431 } |
| 2420 return false; | 2432 return false; |
| 2421 } | 2433 } |
| 2422 if (other.IsMalformed()) { | 2434 if (other.IsMalformed()) { |
| 2423 ASSERT(FLAG_enable_type_checks); | 2435 ASSERT(FLAG_enable_type_checks); |
| 2424 if (malformed_error->IsNull()) { | 2436 if (malformed_error->IsNull()) { |
| 2425 *malformed_error = other.malformed_error(); | 2437 *malformed_error = other.malformed_error(); |
| 2426 } | 2438 } |
| 2427 return false; | 2439 return false; |
| 2428 } | 2440 } |
| 2429 // AbstractType parameters cannot be handled by Class::IsSubtypeOf(). | 2441 // AbstractType parameters cannot be handled by Class::TypeTest(). |
| 2430 // When comparing two uninstantiated function types, one returning type | 2442 // When comparing two uninstantiated function types, one returning type |
| 2431 // parameter K, the other returning type parameter V, we cannot assume that K | 2443 // 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 | 2444 // 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 | 2445 // they have the same index (both are finalized, so their indices are |
| 2434 // comparable). | 2446 // comparable). |
| 2435 // The same rule applies When checking the upper bound of a still | 2447 // The same rule applies When checking the upper bound of a still |
| 2436 // uninstantiated type at compile time. Returning false will defer the test | 2448 // 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. | 2449 // 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 | 2450 // 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 | 2451 // a class B<T> will never require a run time bounds check, even it T is |
| 2440 // uninstantiated at compile time. | 2452 // uninstantiated at compile time. |
| 2441 if (IsTypeParameter() || other.IsTypeParameter()) { | 2453 if (IsTypeParameter()) { |
| 2442 return IsTypeParameter() && other.IsTypeParameter() && | 2454 if (other.IsTypeParameter()) { |
| 2443 (Index() == other.Index()); | 2455 return Index() == other.Index(); |
| 2456 } else { | |
| 2457 // TODO(regis): In checked mode, if the other type is the upper bound of | |
| 2458 // this type parameter, then return true. | |
| 2459 // We would need to keep the upper bound associated to the type parameter. | |
| 2460 } | |
| 2461 return false; | |
| 2462 } | |
| 2463 if (other.IsTypeParameter()) { | |
| 2464 return false; | |
| 2444 } | 2465 } |
| 2445 const Class& cls = Class::Handle(type_class()); | 2466 const Class& cls = Class::Handle(type_class()); |
| 2446 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()), | 2467 return cls.TypeTest(test, |
| 2447 Class::Handle(other.type_class()), | 2468 AbstractTypeArguments::Handle(arguments()), |
| 2448 AbstractTypeArguments::Handle(other.arguments()), | 2469 Class::Handle(other.type_class()), |
| 2449 malformed_error); | 2470 AbstractTypeArguments::Handle(other.arguments()), |
| 2471 malformed_error); | |
| 2450 } | 2472 } |
| 2451 | 2473 |
| 2452 | 2474 |
| 2453 const char* AbstractType::ToCString() const { | 2475 const char* AbstractType::ToCString() const { |
| 2454 // AbstractType is an abstract class. | 2476 // AbstractType is an abstract class. |
| 2455 UNREACHABLE(); | 2477 UNREACHABLE(); |
| 2456 return "AbstractType"; | 2478 return "AbstractType"; |
| 2457 } | 2479 } |
| 2458 | 2480 |
| 2459 | 2481 |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3174 } | 3196 } |
| 3175 const Class& super_class = Class::Handle(cls.SuperClass()); | 3197 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 3176 if (!super_class.IsNull() && | 3198 if (!super_class.IsNull() && |
| 3177 !IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) { | 3199 !IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) { |
| 3178 return false; | 3200 return false; |
| 3179 } | 3201 } |
| 3180 return true; | 3202 return true; |
| 3181 } | 3203 } |
| 3182 | 3204 |
| 3183 | 3205 |
| 3184 bool AbstractTypeArguments::IsSubtypeOf( | 3206 bool AbstractTypeArguments::TypeTest(TypeTestKind test, |
|
srdjan
2012/06/19 20:08:21
ditto
regis
2012/06/19 20:31:47
Done.
| |
| 3185 const AbstractTypeArguments& other, | 3207 const AbstractTypeArguments& other, |
| 3186 intptr_t len, | 3208 intptr_t len, |
| 3187 Error* malformed_error) const { | 3209 Error* malformed_error) const { |
| 3188 ASSERT(Length() >= len); | 3210 ASSERT(Length() >= len); |
| 3189 ASSERT(!other.IsNull()); | 3211 ASSERT(!other.IsNull()); |
| 3190 ASSERT(other.Length() >= len); | 3212 ASSERT(other.Length() >= len); |
| 3191 AbstractType& type = AbstractType::Handle(); | 3213 AbstractType& type = AbstractType::Handle(); |
| 3192 AbstractType& other_type = AbstractType::Handle(); | 3214 AbstractType& other_type = AbstractType::Handle(); |
| 3193 for (intptr_t i = 0; i < len; i++) { | 3215 for (intptr_t i = 0; i < len; i++) { |
| 3194 type = TypeAt(i); | 3216 type = TypeAt(i); |
| 3195 ASSERT(!type.IsNull()); | 3217 ASSERT(!type.IsNull()); |
| 3196 other_type = other.TypeAt(i); | 3218 other_type = other.TypeAt(i); |
| 3197 ASSERT(!other_type.IsNull()); | 3219 ASSERT(!other_type.IsNull()); |
| 3198 if (!type.IsSubtypeOf(other_type, malformed_error)) { | 3220 if (!type.TypeTest(test, other_type, malformed_error)) { |
| 3199 return false; | 3221 return false; |
| 3200 } | 3222 } |
| 3201 } | 3223 } |
| 3202 return true; | 3224 return true; |
| 3203 } | 3225 } |
| 3204 | 3226 |
| 3205 | 3227 |
| 3206 const char* AbstractTypeArguments::ToCString() const { | 3228 const char* AbstractTypeArguments::ToCString() const { |
| 3207 // AbstractTypeArguments is an abstract class, valid only for representing | 3229 // AbstractTypeArguments is an abstract class, valid only for representing |
| 3208 // null. | 3230 // null. |
| (...skipping 6893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10102 const String& str = String::Handle(pattern()); | 10124 const String& str = String::Handle(pattern()); |
| 10103 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10125 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 10104 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10126 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 10105 char* chars = reinterpret_cast<char*>( | 10127 char* chars = reinterpret_cast<char*>( |
| 10106 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10128 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 10107 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10129 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 10108 return chars; | 10130 return chars; |
| 10109 } | 10131 } |
| 10110 | 10132 |
| 10111 } // namespace dart | 10133 } // namespace dart |
| OLD | NEW |