| 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 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 return raw() == Type::Handle(Type::ObjectType()).type_class(); | 1422 return raw() == Type::Handle(Type::ObjectType()).type_class(); |
| 1423 } | 1423 } |
| 1424 | 1424 |
| 1425 | 1425 |
| 1426 bool Class::IsCanonicalSignatureClass() const { | 1426 bool Class::IsCanonicalSignatureClass() const { |
| 1427 const Function& function = Function::Handle(signature_function()); | 1427 const Function& function = Function::Handle(signature_function()); |
| 1428 return (!function.IsNull() && (function.signature_class() == raw())); | 1428 return (!function.IsNull() && (function.signature_class() == raw())); |
| 1429 } | 1429 } |
| 1430 | 1430 |
| 1431 | 1431 |
| 1432 bool Class::IsMoreSpecificThan( | 1432 bool Class::IsSubtypeOf( |
| 1433 const AbstractTypeArguments& type_arguments, | 1433 const AbstractTypeArguments& type_arguments, |
| 1434 const Class& other, | 1434 const Class& other, |
| 1435 const AbstractTypeArguments& other_type_arguments, | 1435 const AbstractTypeArguments& other_type_arguments, |
| 1436 Error* malformed_error) const { | 1436 Error* malformed_error) const { |
| 1437 ASSERT(is_finalized()); |
| 1438 ASSERT(other.is_finalized()); |
| 1437 // Check for DynamicType. | 1439 // Check for DynamicType. |
| 1438 // The DynamicType on the lefthand side is replaced by the bottom type, which | 1440 // The DynamicType on the lefthand side is replaced by the bottom type, which |
| 1439 // is more specific than any type. | 1441 // is more specific than any type. |
| 1440 // Any type is more specific than the DynamicType on the righthand side. | 1442 // Any type is more specific than the DynamicType on the righthand side. |
| 1441 if (IsDynamicClass() || other.IsDynamicClass()) { | 1443 if (IsDynamicClass() || other.IsDynamicClass()) { |
| 1442 return true; | 1444 return true; |
| 1443 } | 1445 } |
| 1444 // Check for reflexivity. | 1446 // Check for reflexivity. |
| 1445 if (raw() == other.raw()) { | 1447 if (raw() == other.raw()) { |
| 1446 const intptr_t len = NumTypeArguments(); | 1448 const intptr_t len = NumTypeArguments(); |
| 1447 if (len == 0) { | 1449 if (len == 0) { |
| 1448 return true; | 1450 return true; |
| 1449 } | 1451 } |
| 1450 // Since we do not truncate the type argument vector of a subclass (see | 1452 // Since we do not truncate the type argument vector of a subclass (see |
| 1451 // below), we only check a prefix of the proper length. | 1453 // below), we only check a prefix of the proper length. |
| 1452 // Check for covariance. | 1454 // Check for covariance. |
| 1453 if (type_arguments.IsNull() || | 1455 if (type_arguments.IsNull() || |
| 1454 other_type_arguments.IsNull() || | 1456 other_type_arguments.IsNull() || |
| 1455 type_arguments.IsDynamicTypes(len) || | 1457 type_arguments.IsDynamicTypes(len) || |
| 1456 other_type_arguments.IsDynamicTypes(len)) { | 1458 other_type_arguments.IsDynamicTypes(len)) { |
| 1457 return true; | 1459 return true; |
| 1458 } | 1460 } |
| 1459 return type_arguments.IsMoreSpecificThan(other_type_arguments, | 1461 return type_arguments.IsSubtypeOf(other_type_arguments, |
| 1460 len, | 1462 len, |
| 1461 malformed_error); | 1463 malformed_error); |
| 1462 } | 1464 } |
| 1463 // Check for two function types. | 1465 // Check for two function types. |
| 1464 if (IsSignatureClass() && other.IsSignatureClass()) { | 1466 if (IsSignatureClass() && other.IsSignatureClass()) { |
| 1465 const Function& fun = Function::Handle(signature_function()); | 1467 const Function& fun = Function::Handle(signature_function()); |
| 1466 const Function& other_fun = Function::Handle(other.signature_function()); | 1468 const Function& other_fun = Function::Handle(other.signature_function()); |
| 1467 return fun.IsSubtypeOf(type_arguments, | 1469 return fun.IsSubtypeOf(type_arguments, |
| 1468 other_fun, | 1470 other_fun, |
| 1469 other_type_arguments, | 1471 other_type_arguments, |
| 1470 malformed_error); | 1472 malformed_error); |
| 1471 } | 1473 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1498 // check from true in production mode to false in checked mode. | 1500 // check from true in production mode to false in checked mode. |
| 1499 if (FLAG_enable_type_checks && !interface_args.IsNull()) { | 1501 if (FLAG_enable_type_checks && !interface_args.IsNull()) { |
| 1500 // Pass type_arguments as bounds instantiator. | 1502 // Pass type_arguments as bounds instantiator. |
| 1501 if (!interface_args.IsWithinBoundsOf(interface_class, | 1503 if (!interface_args.IsWithinBoundsOf(interface_class, |
| 1502 type_arguments, | 1504 type_arguments, |
| 1503 malformed_error)) { | 1505 malformed_error)) { |
| 1504 continue; | 1506 continue; |
| 1505 } | 1507 } |
| 1506 } | 1508 } |
| 1507 } | 1509 } |
| 1508 if (interface_class.IsMoreSpecificThan(interface_args, | 1510 if (interface_class.IsSubtypeOf(interface_args, |
| 1509 other, | 1511 other, |
| 1510 other_type_arguments, | 1512 other_type_arguments, |
| 1511 malformed_error)) { | 1513 malformed_error)) { |
| 1512 return true; | 1514 return true; |
| 1513 } | 1515 } |
| 1514 } | 1516 } |
| 1515 } | 1517 } |
| 1516 // Check the interface case. | 1518 // Check the interface case. |
| 1517 if (is_interface()) { | 1519 if (is_interface()) { |
| 1518 // We already checked the case where 'other' is an interface. Now, 'this', | 1520 // We already checked the case where 'other' is an interface. Now, 'this', |
| 1519 // an interface, cannot be more specific than a class, except class Object, | 1521 // an interface, cannot be more specific than a class, except class Object, |
| 1520 // because although Object is not considered an interface by the vm, it is | 1522 // because although Object is not considered an interface by the vm, it is |
| 1521 // one. In other words, all classes implementing this interface also extend | 1523 // one. In other words, all classes implementing this interface also extend |
| 1522 // class Object. An interface is also more specific than the DynamicType. | 1524 // class Object. An interface is also more specific than the DynamicType. |
| 1523 return (other.IsDynamicClass() || other.IsObjectClass()); | 1525 return (other.IsDynamicClass() || other.IsObjectClass()); |
| 1524 } | 1526 } |
| 1525 const Class& super_class = Class::Handle(SuperClass()); | 1527 const Class& super_class = Class::Handle(SuperClass()); |
| 1526 if (super_class.IsNull()) { | 1528 if (super_class.IsNull()) { |
| 1527 return false; | 1529 return false; |
| 1528 } | 1530 } |
| 1529 // Instead of truncating the type argument vector to the length of the super | 1531 // Instead of truncating the type argument vector to the length of the super |
| 1530 // type argument vector, we make sure that the code works with a vector that | 1532 // type argument vector, we make sure that the code works with a vector that |
| 1531 // is longer than necessary. | 1533 // is longer than necessary. |
| 1532 return super_class.IsMoreSpecificThan(type_arguments, | 1534 return super_class.IsSubtypeOf(type_arguments, |
| 1533 other, | 1535 other, |
| 1534 other_type_arguments, | 1536 other_type_arguments, |
| 1535 malformed_error); | 1537 malformed_error); |
| 1536 } | 1538 } |
| 1537 | 1539 |
| 1538 | 1540 |
| 1539 bool Class::IsTopLevel() const { | 1541 bool Class::IsTopLevel() const { |
| 1540 return String::Handle(Name()).Equals("::"); | 1542 return String::Handle(Name()).Equals("::"); |
| 1541 } | 1543 } |
| 1542 | 1544 |
| 1543 | 1545 |
| 1544 bool Class::TestType(TypeTestKind test, | |
| 1545 const AbstractTypeArguments& type_arguments, | |
| 1546 const Class& other, | |
| 1547 const AbstractTypeArguments& other_type_arguments, | |
| 1548 Error* malformed_error) const { | |
| 1549 ASSERT(is_finalized() || !ClassFinalizer::AllClassesFinalized()); | |
| 1550 ASSERT(other.is_finalized() || !ClassFinalizer::AllClassesFinalized()); | |
| 1551 if (test == kIsAssignableTo) { | |
| 1552 // The spec states that "a type T is assignable to a type S if T is a | |
| 1553 // subtype of S or S is a subtype of T". This is from the perspective of a | |
| 1554 // static checker, which does not know the actual type of the assigned | |
| 1555 // value. However, this type information is available at run time in checked | |
| 1556 // mode. We therefore apply a more restrictive subtype check, which prevents | |
| 1557 // heap pollution. We only keep the assignability check when assigning | |
| 1558 // values of a function type. | |
| 1559 if (IsSignatureClass() && other.IsSignatureClass()) { | |
| 1560 const Function& src_fun = Function::Handle(signature_function()); | |
| 1561 const Function& dst_fun = Function::Handle(other.signature_function()); | |
| 1562 return src_fun.IsAssignableTo(type_arguments, | |
| 1563 dst_fun, | |
| 1564 other_type_arguments, | |
| 1565 malformed_error); | |
| 1566 } | |
| 1567 // Continue with a subtype test. | |
| 1568 test = kIsSubtypeOf; | |
| 1569 } | |
| 1570 ASSERT(test == kIsSubtypeOf); | |
| 1571 | |
| 1572 // Check for "more specific" relation. | |
| 1573 return IsMoreSpecificThan(type_arguments, other, other_type_arguments, | |
| 1574 malformed_error); | |
| 1575 } | |
| 1576 | |
| 1577 | |
| 1578 RawFunction* Class::LookupDynamicFunction(const String& name) const { | 1546 RawFunction* Class::LookupDynamicFunction(const String& name) const { |
| 1579 Function& function = Function::Handle(LookupFunction(name)); | 1547 Function& function = Function::Handle(LookupFunction(name)); |
| 1580 if (function.IsNull() || !function.IsDynamicFunction()) { | 1548 if (function.IsNull() || !function.IsDynamicFunction()) { |
| 1581 return Function::null(); | 1549 return Function::null(); |
| 1582 } | 1550 } |
| 1583 return function.raw(); | 1551 return function.raw(); |
| 1584 } | 1552 } |
| 1585 | 1553 |
| 1586 | 1554 |
| 1587 RawFunction* Class::LookupStaticFunction(const String& name) const { | 1555 RawFunction* Class::LookupStaticFunction(const String& name) const { |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2121 (type_class() == Type::Handle(Type::FunctionInterface()).type_class()); | 2089 (type_class() == Type::Handle(Type::FunctionInterface()).type_class()); |
| 2122 } | 2090 } |
| 2123 | 2091 |
| 2124 | 2092 |
| 2125 bool AbstractType::IsListInterface() const { | 2093 bool AbstractType::IsListInterface() const { |
| 2126 return HasResolvedTypeClass() && | 2094 return HasResolvedTypeClass() && |
| 2127 (type_class() == Type::Handle(Type::ListInterface()).type_class()); | 2095 (type_class() == Type::Handle(Type::ListInterface()).type_class()); |
| 2128 } | 2096 } |
| 2129 | 2097 |
| 2130 | 2098 |
| 2131 bool AbstractType::IsMoreSpecificThan(const AbstractType& other, | 2099 bool AbstractType::IsSubtypeOf(const AbstractType& other, |
| 2132 Error* malformed_error) const { | 2100 Error* malformed_error) const { |
| 2133 ASSERT(IsFinalized()); | 2101 ASSERT(IsFinalized()); |
| 2134 ASSERT(other.IsFinalized()); | 2102 ASSERT(other.IsFinalized()); |
| 2135 // AbstractType parameters cannot be handled by Class::IsMoreSpecificThan(). | 2103 // AbstractType parameters cannot be handled by Class::IsSubtypeOf(). |
| 2136 if (IsTypeParameter() || other.IsTypeParameter()) { | 2104 if (IsTypeParameter() || other.IsTypeParameter()) { |
| 2137 return IsTypeParameter() && other.IsTypeParameter() && | 2105 return IsTypeParameter() && other.IsTypeParameter() && |
| 2138 (Index() == other.Index()); | 2106 (Index() == other.Index()); |
| 2139 } | 2107 } |
| 2140 const Class& cls = Class::Handle(type_class()); | 2108 const Class& cls = Class::Handle(type_class()); |
| 2141 return cls.IsMoreSpecificThan( | 2109 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()), |
| 2142 AbstractTypeArguments::Handle(arguments()), | 2110 Class::Handle(other.type_class()), |
| 2143 Class::Handle(other.type_class()), | 2111 AbstractTypeArguments::Handle(other.arguments()), |
| 2144 AbstractTypeArguments::Handle(other.arguments()), | 2112 malformed_error); |
| 2145 malformed_error); | |
| 2146 } | |
| 2147 | |
| 2148 | |
| 2149 bool AbstractType::Test(TypeTestKind test, | |
| 2150 const AbstractType& other, | |
| 2151 Error* malformed_error) const { | |
| 2152 ASSERT(IsFinalized()); | |
| 2153 ASSERT(other.IsFinalized()); | |
| 2154 // AbstractType parameters cannot be handled by Class::TestType(). | |
| 2155 if (IsTypeParameter() || other.IsTypeParameter()) { | |
| 2156 return IsTypeParameter() && other.IsTypeParameter() && | |
| 2157 (Index() == other.Index()); | |
| 2158 } | |
| 2159 const Class& cls = Class::Handle(type_class()); | |
| 2160 if (test == kIsSubtypeOf) { | |
| 2161 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()), | |
| 2162 Class::Handle(other.type_class()), | |
| 2163 AbstractTypeArguments::Handle(other.arguments()), | |
| 2164 malformed_error); | |
| 2165 } else { | |
| 2166 ASSERT(test == kIsAssignableTo); | |
| 2167 return cls.IsAssignableTo(AbstractTypeArguments::Handle(arguments()), | |
| 2168 Class::Handle(other.type_class()), | |
| 2169 AbstractTypeArguments::Handle(other.arguments()), | |
| 2170 malformed_error); | |
| 2171 } | |
| 2172 } | 2113 } |
| 2173 | 2114 |
| 2174 RawAbstractType* AbstractType::NewTypeParameter( | 2115 RawAbstractType* AbstractType::NewTypeParameter( |
| 2175 intptr_t index, const String& name, intptr_t token_index) { | 2116 intptr_t index, const String& name, intptr_t token_index) { |
| 2176 return TypeParameter::New(index, name, token_index); | 2117 return TypeParameter::New(index, name, token_index); |
| 2177 } | 2118 } |
| 2178 | 2119 |
| 2179 | 2120 |
| 2180 RawAbstractType* AbstractType::NewInstantiatedType( | 2121 RawAbstractType* AbstractType::NewInstantiatedType( |
| 2181 const AbstractType& uninstantiated_type, | 2122 const AbstractType& uninstantiated_type, |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2829 ASSERT(super_type.IsFinalized()); | 2770 ASSERT(super_type.IsFinalized()); |
| 2830 const Class& super_class = Class::Handle(super_type.type_class()); | 2771 const Class& super_class = Class::Handle(super_type.type_class()); |
| 2831 if (!IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) { | 2772 if (!IsWithinBoundsOf(super_class, bounds_instantiator, malformed_error)) { |
| 2832 return false; | 2773 return false; |
| 2833 } | 2774 } |
| 2834 } | 2775 } |
| 2835 return true; | 2776 return true; |
| 2836 } | 2777 } |
| 2837 | 2778 |
| 2838 | 2779 |
| 2839 bool AbstractTypeArguments::IsMoreSpecificThan( | 2780 bool AbstractTypeArguments::IsSubtypeOf( |
| 2840 const AbstractTypeArguments& other, | 2781 const AbstractTypeArguments& other, |
| 2841 intptr_t len, | 2782 intptr_t len, |
| 2842 Error* malformed_error) const { | 2783 Error* malformed_error) const { |
| 2843 ASSERT(Length() >= len); | 2784 ASSERT(Length() >= len); |
| 2844 ASSERT(!other.IsNull()); | 2785 ASSERT(!other.IsNull()); |
| 2845 ASSERT(other.Length() >= len); | 2786 ASSERT(other.Length() >= len); |
| 2846 AbstractType& type = AbstractType::Handle(); | 2787 AbstractType& type = AbstractType::Handle(); |
| 2847 AbstractType& other_type = AbstractType::Handle(); | 2788 AbstractType& other_type = AbstractType::Handle(); |
| 2848 for (intptr_t i = 0; i < len; i++) { | 2789 for (intptr_t i = 0; i < len; i++) { |
| 2849 type = TypeAt(i); | 2790 type = TypeAt(i); |
| 2850 ASSERT(!type.IsNull()); | 2791 ASSERT(!type.IsNull()); |
| 2851 other_type = other.TypeAt(i); | 2792 other_type = other.TypeAt(i); |
| 2852 ASSERT(!other_type.IsNull()); | 2793 ASSERT(!other_type.IsNull()); |
| 2853 if (!type.IsMoreSpecificThan(other_type, malformed_error)) { | 2794 if (!type.IsSubtypeOf(other_type, malformed_error)) { |
| 2854 return false; | 2795 return false; |
| 2855 } | 2796 } |
| 2856 } | 2797 } |
| 2857 return true; | 2798 return true; |
| 2858 } | 2799 } |
| 2859 | 2800 |
| 2860 | 2801 |
| 2861 const char* AbstractTypeArguments::ToCString() const { | 2802 const char* AbstractTypeArguments::ToCString() const { |
| 2862 // AbstractTypeArguments is an abstract class, valid only for representing | 2803 // AbstractTypeArguments is an abstract class, valid only for representing |
| 2863 // null. | 2804 // null. |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3423 return true; | 3364 return true; |
| 3424 } | 3365 } |
| 3425 if (!param_type.IsSubtypeOf(other_param_type, malformed_error) && | 3366 if (!param_type.IsSubtypeOf(other_param_type, malformed_error) && |
| 3426 !other_param_type.IsSubtypeOf(param_type, malformed_error)) { | 3367 !other_param_type.IsSubtypeOf(param_type, malformed_error)) { |
| 3427 return false; | 3368 return false; |
| 3428 } | 3369 } |
| 3429 return true; | 3370 return true; |
| 3430 } | 3371 } |
| 3431 | 3372 |
| 3432 | 3373 |
| 3433 bool Function::TestType( | 3374 bool Function::IsSubtypeOf( |
| 3434 TypeTestKind test, | |
| 3435 const AbstractTypeArguments& type_arguments, | 3375 const AbstractTypeArguments& type_arguments, |
| 3436 const Function& other, | 3376 const Function& other, |
| 3437 const AbstractTypeArguments& other_type_arguments, | 3377 const AbstractTypeArguments& other_type_arguments, |
| 3438 Error* malformed_error) const { | 3378 Error* malformed_error) const { |
| 3439 const intptr_t num_fixed_params = num_fixed_parameters(); | 3379 const intptr_t num_fixed_params = num_fixed_parameters(); |
| 3440 const intptr_t num_opt_params = num_optional_parameters(); | 3380 const intptr_t num_opt_params = num_optional_parameters(); |
| 3441 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 3381 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
| 3442 const intptr_t other_num_opt_params = other.num_optional_parameters(); | 3382 const intptr_t other_num_opt_params = other.num_optional_parameters(); |
| 3443 if ((num_fixed_params != other_num_fixed_params) || | 3383 if ((num_fixed_params != other_num_fixed_params) || |
| 3444 ((test == AbstractType::kIsSubtypeOf) && | 3384 (num_opt_params < other_num_opt_params)) { |
| 3445 (num_opt_params < other_num_opt_params))) { | |
| 3446 return false; | 3385 return false; |
| 3447 } | 3386 } |
| 3448 // Check the result type. | 3387 // Check the result type. |
| 3449 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); | 3388 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); |
| 3450 if (!other_res_type.IsInstantiated()) { | 3389 if (!other_res_type.IsInstantiated()) { |
| 3451 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); | 3390 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); |
| 3452 } | 3391 } |
| 3453 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { | 3392 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { |
| 3454 AbstractType& res_type = AbstractType::Handle(result_type()); | 3393 AbstractType& res_type = AbstractType::Handle(result_type()); |
| 3455 if (!res_type.IsInstantiated()) { | 3394 if (!res_type.IsInstantiated()) { |
| 3456 res_type = res_type.InstantiateFrom(type_arguments); | 3395 res_type = res_type.InstantiateFrom(type_arguments); |
| 3457 } | 3396 } |
| 3458 if (!res_type.IsDynamicType() && | 3397 if (!res_type.IsDynamicType() && |
| 3459 (res_type.IsVoidType() || | 3398 (res_type.IsVoidType() || |
| 3460 !(res_type.IsSubtypeOf(other_res_type, malformed_error) || | 3399 !(res_type.IsSubtypeOf(other_res_type, malformed_error) || |
| 3461 other_res_type.IsSubtypeOf(res_type, malformed_error)))) { | 3400 other_res_type.IsSubtypeOf(res_type, malformed_error)))) { |
| 3462 return false; | 3401 return false; |
| 3463 } | 3402 } |
| 3464 } | 3403 } |
| 3465 // Check the types of fixed parameters. | 3404 // Check the types of fixed parameters. |
| 3466 for (intptr_t i = 0; i < num_fixed_params; i++) { | 3405 for (intptr_t i = 0; i < num_fixed_params; i++) { |
| 3467 if (!TestParameterType(i, type_arguments, other, other_type_arguments, | 3406 if (!TestParameterType(i, type_arguments, other, other_type_arguments, |
| 3468 malformed_error)) { | 3407 malformed_error)) { |
| 3469 return false; | 3408 return false; |
| 3470 } | 3409 } |
| 3471 } | 3410 } |
| 3472 // Check the names and types of optional parameters. | 3411 // Check the names and types of optional parameters. |
| 3473 if (num_opt_params >= other_num_opt_params) { | 3412 // Check that for each optional named parameter of type T of the other |
| 3474 // Check that for each optional named parameter of type T of the other | 3413 // function type, there is a corresponding optional named parameter of this |
| 3475 // function type, there is a corresponding optional named parameter of this | 3414 // function at the same position with an identical name and with a type S |
| 3476 // function at the same position with an identical name and with a type S | 3415 // that is a subtype or supertype of T. |
| 3477 // that is a subtype or supertype of T. | |
| 3478 // Note that SetParameterNameAt() guarantees that names are symbols, so we | |
| 3479 // can compare their raw pointers. | |
| 3480 const intptr_t other_num_params = | |
| 3481 other_num_fixed_params + other_num_opt_params; | |
| 3482 String& other_param_name = String::Handle(); | |
| 3483 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | |
| 3484 other_param_name = other.ParameterNameAt(i); | |
| 3485 if ((ParameterNameAt(i) != other_param_name.raw()) || | |
| 3486 !TestParameterType(i, type_arguments, other, other_type_arguments, | |
| 3487 malformed_error)) { | |
| 3488 return false; | |
| 3489 } | |
| 3490 } | |
| 3491 return true; | |
| 3492 } | |
| 3493 ASSERT((test == AbstractType::kIsAssignableTo) && | |
| 3494 (num_opt_params < other_num_opt_params)); | |
| 3495 // To verify that this function type is assignable to the other function type, | |
| 3496 // check that for each optional named parameter of type T of this function | |
| 3497 // type, there is a corresponding optional named parameter of the other | |
| 3498 // function at the same position with an identical name and with a type S that | |
| 3499 // is a subtype or supertype of T. | |
| 3500 // Note that SetParameterNameAt() guarantees that names are symbols, so we | 3416 // Note that SetParameterNameAt() guarantees that names are symbols, so we |
| 3501 // can compare their raw pointers. | 3417 // can compare their raw pointers. |
| 3502 const intptr_t num_params = num_fixed_params + num_opt_params; | 3418 const intptr_t other_num_params = |
| 3419 other_num_fixed_params + other_num_opt_params; |
| 3503 String& other_param_name = String::Handle(); | 3420 String& other_param_name = String::Handle(); |
| 3504 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 3421 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
| 3505 other_param_name = other.ParameterNameAt(i); | 3422 other_param_name = other.ParameterNameAt(i); |
| 3506 if ((ParameterNameAt(i) != other_param_name.raw()) || | 3423 if ((ParameterNameAt(i) != other_param_name.raw()) || |
| 3507 !TestParameterType(i, type_arguments, other, other_type_arguments, | 3424 !TestParameterType(i, type_arguments, other, other_type_arguments, |
| 3508 malformed_error)) { | 3425 malformed_error)) { |
| 3509 return false; | 3426 return false; |
| 3510 } | 3427 } |
| 3511 } | 3428 } |
| 3512 return true; | 3429 return true; |
| 3513 } | 3430 } |
| 3514 | 3431 |
| (...skipping 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6246 | 6163 |
| 6247 | 6164 |
| 6248 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const { | 6165 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const { |
| 6249 const Class& cls = Class::Handle(clazz()); | 6166 const Class& cls = Class::Handle(clazz()); |
| 6250 intptr_t field_offset = cls.type_arguments_instance_field_offset(); | 6167 intptr_t field_offset = cls.type_arguments_instance_field_offset(); |
| 6251 ASSERT(field_offset != Class::kNoTypeArguments); | 6168 ASSERT(field_offset != Class::kNoTypeArguments); |
| 6252 *FieldAddrAtOffset(field_offset) = value.Canonicalize(); | 6169 *FieldAddrAtOffset(field_offset) = value.Canonicalize(); |
| 6253 } | 6170 } |
| 6254 | 6171 |
| 6255 | 6172 |
| 6256 bool Instance::TestType(TypeTestKind test, | 6173 bool Instance::IsInstanceOf(const AbstractType& other, |
| 6257 const AbstractType& other, | 6174 const AbstractTypeArguments& other_instantiator, |
| 6258 const AbstractTypeArguments& other_instantiator, | 6175 Error* malformed_error) const { |
| 6259 Error* malformed_error) const { | |
| 6260 ASSERT(other.IsFinalized()); | 6176 ASSERT(other.IsFinalized()); |
| 6261 ASSERT(!other.IsDynamicType()); | 6177 ASSERT(!other.IsDynamicType()); |
| 6262 ASSERT(!other.IsVoidType()); | 6178 ASSERT(!other.IsVoidType()); |
| 6263 if (IsNull()) { | 6179 if (IsNull()) { |
| 6264 if (test == AbstractType::kIsSubtypeOf) { | 6180 Class& other_class = Class::Handle(); |
| 6265 Class& other_class = Class::Handle(); | 6181 if (other.IsTypeParameter()) { |
| 6266 if (other.IsTypeParameter()) { | 6182 if (other_instantiator.IsNull()) { |
| 6267 if (other_instantiator.IsNull()) { | 6183 return true; // Other type is uninstantiated, i.e. Dynamic. |
| 6268 return true; // Other type is uninstantiated, i.e. Dynamic. | |
| 6269 } | |
| 6270 const AbstractType& instantiated_other = | |
| 6271 AbstractType::Handle(other_instantiator.TypeAt(other.Index())); | |
| 6272 ASSERT(instantiated_other.IsInstantiated()); | |
| 6273 other_class = instantiated_other.type_class(); | |
| 6274 } else { | |
| 6275 other_class = other.type_class(); | |
| 6276 } | 6184 } |
| 6277 return other_class.IsObjectClass() || other_class.IsDynamicClass(); | 6185 const AbstractType& instantiated_other = |
| 6186 AbstractType::Handle(other_instantiator.TypeAt(other.Index())); |
| 6187 ASSERT(instantiated_other.IsInstantiated()); |
| 6188 other_class = instantiated_other.type_class(); |
| 6278 } else { | 6189 } else { |
| 6279 ASSERT(test == AbstractType::kIsAssignableTo); | 6190 other_class = other.type_class(); |
| 6280 return true; | |
| 6281 } | 6191 } |
| 6192 return other_class.IsObjectClass() || other_class.IsDynamicClass(); |
| 6282 } | 6193 } |
| 6283 const Class& cls = Class::Handle(clazz()); | 6194 const Class& cls = Class::Handle(clazz()); |
| 6284 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); | 6195 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); |
| 6285 const intptr_t num_type_arguments = cls.NumTypeArguments(); | 6196 const intptr_t num_type_arguments = cls.NumTypeArguments(); |
| 6286 if (num_type_arguments > 0) { | 6197 if (num_type_arguments > 0) { |
| 6287 type_arguments = GetTypeArguments(); | 6198 type_arguments = GetTypeArguments(); |
| 6288 // Verify that the number of type arguments in the instance matches the | 6199 // Verify that the number of type arguments in the instance matches the |
| 6289 // number of type arguments expected by the instance class. | 6200 // number of type arguments expected by the instance class. |
| 6290 // A discrepancy is allowed for closures, which borrow the type argument | 6201 // A discrepancy is allowed for closures, which borrow the type argument |
| 6291 // vector of their instantiator, which may be of a super class of the class | 6202 // vector of their instantiator, which may be of a super class of the class |
| (...skipping 21 matching lines...) Expand all Loading... |
| 6313 other_type_arguments = instantiated_other.arguments(); | 6224 other_type_arguments = instantiated_other.arguments(); |
| 6314 } else { | 6225 } else { |
| 6315 other_class = other.type_class(); | 6226 other_class = other.type_class(); |
| 6316 other_type_arguments = other.arguments(); | 6227 other_type_arguments = other.arguments(); |
| 6317 if (!other_type_arguments.IsNull() && | 6228 if (!other_type_arguments.IsNull() && |
| 6318 !other_type_arguments.IsInstantiated()) { | 6229 !other_type_arguments.IsInstantiated()) { |
| 6319 other_type_arguments = | 6230 other_type_arguments = |
| 6320 other_type_arguments.InstantiateFrom(other_instantiator); | 6231 other_type_arguments.InstantiateFrom(other_instantiator); |
| 6321 } | 6232 } |
| 6322 } | 6233 } |
| 6323 return cls.TestType(test, type_arguments, other_class, other_type_arguments, | 6234 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |
| 6324 malformed_error); | 6235 malformed_error); |
| 6325 } | 6236 } |
| 6326 | 6237 |
| 6327 | 6238 |
| 6328 bool Instance::IsValidNativeIndex(int index) const { | 6239 bool Instance::IsValidNativeIndex(int index) const { |
| 6329 const Class& cls = Class::Handle(clazz()); | 6240 const Class& cls = Class::Handle(clazz()); |
| 6330 return (index >= 0 && index < cls.num_native_fields()); | 6241 return (index >= 0 && index < cls.num_native_fields()); |
| 6331 } | 6242 } |
| 6332 | 6243 |
| 6333 | 6244 |
| 6334 RawInstance* Instance::New(const Class& cls, Heap::Space space) { | 6245 RawInstance* Instance::New(const Class& cls, Heap::Space space) { |
| (...skipping 2523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8858 const String& str = String::Handle(pattern()); | 8769 const String& str = String::Handle(pattern()); |
| 8859 const char* format = "JSRegExp: pattern=%s flags=%s"; | 8770 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 8860 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 8771 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 8861 char* chars = reinterpret_cast<char*>( | 8772 char* chars = reinterpret_cast<char*>( |
| 8862 Isolate::Current()->current_zone()->Allocate(len + 1)); | 8773 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 8863 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 8774 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 8864 return chars; | 8775 return chars; |
| 8865 } | 8776 } |
| 8866 | 8777 |
| 8867 } // namespace dart | 8778 } // namespace dart |
| OLD | NEW |