Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: runtime/vm/object.cc

Issue 9664029: Fix type check to perform a subtype test at top level instead of an (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698