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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 3383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3394 } | 3394 } |
3395 | 3395 |
3396 | 3396 |
3397 bool AbstractTypeArguments::IsResolved() const { | 3397 bool AbstractTypeArguments::IsResolved() const { |
3398 // AbstractTypeArguments is an abstract class. | 3398 // AbstractTypeArguments is an abstract class. |
3399 UNREACHABLE(); | 3399 UNREACHABLE(); |
3400 return false; | 3400 return false; |
3401 } | 3401 } |
3402 | 3402 |
3403 | 3403 |
3404 bool AbstractTypeArguments::IsInstantiated() const { | 3404 bool AbstractTypeArguments::IsInstantiated(GrowableObjectArray* trail) const { |
3405 // AbstractTypeArguments is an abstract class. | 3405 // AbstractTypeArguments is an abstract class. |
3406 UNREACHABLE(); | 3406 UNREACHABLE(); |
3407 return false; | 3407 return false; |
3408 } | 3408 } |
3409 | 3409 |
3410 | 3410 |
3411 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { | 3411 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { |
3412 // AbstractTypeArguments is an abstract class. | 3412 // AbstractTypeArguments is an abstract class. |
3413 UNREACHABLE(); | 3413 UNREACHABLE(); |
3414 return false; | 3414 return false; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3472 strings.SetAt(s++, Symbols::CommaSpace()); | 3472 strings.SetAt(s++, Symbols::CommaSpace()); |
3473 } | 3473 } |
3474 } | 3474 } |
3475 strings.SetAt(s++, Symbols::RAngleBracket()); | 3475 strings.SetAt(s++, Symbols::RAngleBracket()); |
3476 ASSERT(s == num_strings); | 3476 ASSERT(s == num_strings); |
3477 name = String::ConcatAll(strings); | 3477 name = String::ConcatAll(strings); |
3478 return Symbols::New(name); | 3478 return Symbols::New(name); |
3479 } | 3479 } |
3480 | 3480 |
3481 | 3481 |
3482 bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const { | 3482 bool AbstractTypeArguments::IsEquivalent(const AbstractTypeArguments& other, |
3483 GrowableObjectArray* trail) const { | |
3483 if (this->raw() == other.raw()) { | 3484 if (this->raw() == other.raw()) { |
3484 return true; | 3485 return true; |
3485 } | 3486 } |
3486 if (IsNull() || other.IsNull()) { | 3487 if (IsNull() || other.IsNull()) { |
3487 return false; | 3488 return false; |
3488 } | 3489 } |
3489 const intptr_t num_types = Length(); | 3490 const intptr_t num_types = Length(); |
3490 if (num_types != other.Length()) { | 3491 if (num_types != other.Length()) { |
3491 return false; | 3492 return false; |
3492 } | 3493 } |
3493 AbstractType& type = AbstractType::Handle(); | 3494 AbstractType& type = AbstractType::Handle(); |
3494 AbstractType& other_type = AbstractType::Handle(); | 3495 AbstractType& other_type = AbstractType::Handle(); |
3495 for (intptr_t i = 0; i < num_types; i++) { | 3496 for (intptr_t i = 0; i < num_types; i++) { |
3496 type = TypeAt(i); | 3497 type = TypeAt(i); |
3497 other_type = other.TypeAt(i); | 3498 other_type = other.TypeAt(i); |
3498 if (!type.Equals(other_type)) { | 3499 if (!type.IsEquivalent(other_type, trail)) { |
3499 return false; | 3500 return false; |
3500 } | 3501 } |
3501 } | 3502 } |
3502 return true; | 3503 return true; |
3503 } | 3504 } |
3504 | 3505 |
3505 | 3506 |
3506 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( | 3507 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( |
3507 const AbstractTypeArguments& instantiator_type_arguments, | 3508 const AbstractTypeArguments& instantiator_type_arguments, |
3508 Error* bound_error) const { | 3509 Error* bound_error, |
3510 GrowableObjectArray* trail) const { | |
3509 // AbstractTypeArguments is an abstract class. | 3511 // AbstractTypeArguments is an abstract class. |
3510 UNREACHABLE(); | 3512 UNREACHABLE(); |
3511 return NULL; | 3513 return NULL; |
3512 } | 3514 } |
3513 | 3515 |
3514 | 3516 |
3515 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, | 3517 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, |
3516 intptr_t from_index, | 3518 intptr_t from_index, |
3517 intptr_t len) const { | 3519 intptr_t len) const { |
3518 ASSERT(Length() >= (from_index + len)); | 3520 ASSERT(Length() >= (from_index + len)); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3607 for (intptr_t i = 0; i < num_types; i++) { | 3609 for (intptr_t i = 0; i < num_types; i++) { |
3608 type = TypeAt(i); | 3610 type = TypeAt(i); |
3609 if (!type.IsResolved()) { | 3611 if (!type.IsResolved()) { |
3610 return false; | 3612 return false; |
3611 } | 3613 } |
3612 } | 3614 } |
3613 return true; | 3615 return true; |
3614 } | 3616 } |
3615 | 3617 |
3616 | 3618 |
3617 bool TypeArguments::IsInstantiated() const { | 3619 bool TypeArguments::IsInstantiated(GrowableObjectArray* trail) const { |
3618 AbstractType& type = AbstractType::Handle(); | 3620 AbstractType& type = AbstractType::Handle(); |
3619 const intptr_t num_types = Length(); | 3621 const intptr_t num_types = Length(); |
3620 for (intptr_t i = 0; i < num_types; i++) { | 3622 for (intptr_t i = 0; i < num_types; i++) { |
3621 type = TypeAt(i); | 3623 type = TypeAt(i); |
3622 ASSERT(!type.IsNull()); | 3624 ASSERT(!type.IsNull()); |
3623 if (!type.IsInstantiated()) { | 3625 if (!type.IsInstantiated(trail)) { |
3624 return false; | 3626 return false; |
3625 } | 3627 } |
3626 } | 3628 } |
3627 return true; | 3629 return true; |
3628 } | 3630 } |
3629 | 3631 |
3630 | 3632 |
3631 bool TypeArguments::IsUninstantiatedIdentity() const { | 3633 bool TypeArguments::IsUninstantiatedIdentity() const { |
3632 ASSERT(!IsInstantiated()); | 3634 ASSERT(!IsInstantiated()); |
3633 AbstractType& type = AbstractType::Handle(); | 3635 AbstractType& type = AbstractType::Handle(); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3763 if (!type_args.IsNull() && type_args.IsBounded()) { | 3765 if (!type_args.IsNull() && type_args.IsBounded()) { |
3764 return true; | 3766 return true; |
3765 } | 3767 } |
3766 } | 3768 } |
3767 return false; | 3769 return false; |
3768 } | 3770 } |
3769 | 3771 |
3770 | 3772 |
3771 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( | 3773 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( |
3772 const AbstractTypeArguments& instantiator_type_arguments, | 3774 const AbstractTypeArguments& instantiator_type_arguments, |
3773 Error* bound_error) const { | 3775 Error* bound_error, |
3776 GrowableObjectArray* trail) const { | |
3774 ASSERT(!IsInstantiated()); | 3777 ASSERT(!IsInstantiated()); |
3775 if (!instantiator_type_arguments.IsNull() && | 3778 if (!instantiator_type_arguments.IsNull() && |
3776 IsUninstantiatedIdentity() && | 3779 IsUninstantiatedIdentity() && |
3777 (instantiator_type_arguments.Length() == Length())) { | 3780 (instantiator_type_arguments.Length() == Length())) { |
3778 return instantiator_type_arguments.raw(); | 3781 return instantiator_type_arguments.raw(); |
3779 } | 3782 } |
3780 const intptr_t num_types = Length(); | 3783 const intptr_t num_types = Length(); |
3781 TypeArguments& instantiated_array = | 3784 TypeArguments& instantiated_array = |
3782 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); | 3785 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); |
3783 AbstractType& type = AbstractType::Handle(); | 3786 AbstractType& type = AbstractType::Handle(); |
3784 for (intptr_t i = 0; i < num_types; i++) { | 3787 for (intptr_t i = 0; i < num_types; i++) { |
3785 type = TypeAt(i); | 3788 type = TypeAt(i); |
3786 if (!type.IsInstantiated()) { | 3789 if (!type.IsInstantiated()) { |
3787 type = type.InstantiateFrom(instantiator_type_arguments, bound_error); | 3790 type = type.InstantiateFrom(instantiator_type_arguments, |
3791 bound_error, | |
3792 trail); | |
3788 } | 3793 } |
3789 instantiated_array.SetTypeAt(i, type); | 3794 instantiated_array.SetTypeAt(i, type); |
3790 } | 3795 } |
3791 return instantiated_array.raw(); | 3796 return instantiated_array.raw(); |
3792 } | 3797 } |
3793 | 3798 |
3794 | 3799 |
3795 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { | 3800 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { |
3796 if (len < 0 || len > kMaxElements) { | 3801 if (len < 0 || len > kMaxElements) { |
3797 // This should be caught before we reach here. | 3802 // This should be caught before we reach here. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3908 TypeArguments::New(num_types)); | 3913 TypeArguments::New(num_types)); |
3909 for (intptr_t i = 0; i < num_types; i++) { | 3914 for (intptr_t i = 0; i < num_types; i++) { |
3910 type = TypeAt(i); | 3915 type = TypeAt(i); |
3911 type = type.CloneUnfinalized(); | 3916 type = type.CloneUnfinalized(); |
3912 clone.SetTypeAt(i, type); | 3917 clone.SetTypeAt(i, type); |
3913 } | 3918 } |
3914 return clone.raw(); | 3919 return clone.raw(); |
3915 } | 3920 } |
3916 | 3921 |
3917 | 3922 |
3918 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { | 3923 RawAbstractTypeArguments* TypeArguments::Canonicalize( |
3924 GrowableObjectArray* trail) const { | |
3919 if (IsNull() || IsCanonical()) { | 3925 if (IsNull() || IsCanonical()) { |
3920 ASSERT(IsOld()); | 3926 ASSERT(IsOld()); |
3921 return this->raw(); | 3927 return this->raw(); |
3922 } | 3928 } |
3923 Isolate* isolate = Isolate::Current(); | 3929 Isolate* isolate = Isolate::Current(); |
3924 ObjectStore* object_store = isolate->object_store(); | 3930 ObjectStore* object_store = isolate->object_store(); |
3925 const Array& table = Array::Handle(isolate, | 3931 const Array& table = Array::Handle(isolate, |
3926 object_store->canonical_type_arguments()); | 3932 object_store->canonical_type_arguments()); |
3927 ASSERT(table.Length() > 0); | 3933 ASSERT(table.Length() > 0); |
3928 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, | 3934 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, |
3929 table, | 3935 table, |
3930 *this, | 3936 *this, |
3931 Hash()); | 3937 Hash()); |
3932 TypeArguments& result = TypeArguments::Handle(isolate); | 3938 TypeArguments& result = TypeArguments::Handle(isolate); |
3933 result ^= table.At(index); | 3939 result ^= table.At(index); |
3934 if (result.IsNull()) { | 3940 if (result.IsNull()) { |
3935 // Canonicalize each type argument. | 3941 // Canonicalize each type argument. |
3936 const intptr_t num_types = Length(); | 3942 const intptr_t num_types = Length(); |
3937 AbstractType& type = AbstractType::Handle(isolate); | 3943 AbstractType& type = AbstractType::Handle(isolate); |
3938 for (intptr_t i = 0; i < num_types; i++) { | 3944 for (intptr_t i = 0; i < num_types; i++) { |
3939 type = TypeAt(i); | 3945 type = TypeAt(i); |
3940 type = type.Canonicalize(); | 3946 type = type.Canonicalize(trail); |
3941 SetTypeAt(i, type); | 3947 SetTypeAt(i, type); |
3942 } | 3948 } |
3943 // Make sure we have an old space object and add it to the table. | 3949 // Make sure we have an old space object and add it to the table. |
3944 if (this->IsNew()) { | 3950 if (this->IsNew()) { |
3945 result ^= Object::Clone(*this, Heap::kOld); | 3951 result ^= Object::Clone(*this, Heap::kOld); |
3946 } else { | 3952 } else { |
3947 result ^= this->raw(); | 3953 result ^= this->raw(); |
3948 } | 3954 } |
3949 ASSERT(result.IsOld()); | 3955 ASSERT(result.IsOld()); |
3950 InsertIntoCanonicalTypeArguments(isolate, table, result, index); | 3956 InsertIntoCanonicalTypeArguments(isolate, table, result, index); |
(...skipping 7596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11547 } | 11553 } |
11548 | 11554 |
11549 | 11555 |
11550 intptr_t AbstractType::token_pos() const { | 11556 intptr_t AbstractType::token_pos() const { |
11551 // AbstractType is an abstract class. | 11557 // AbstractType is an abstract class. |
11552 UNREACHABLE(); | 11558 UNREACHABLE(); |
11553 return -1; | 11559 return -1; |
11554 } | 11560 } |
11555 | 11561 |
11556 | 11562 |
11557 bool AbstractType::IsInstantiated() const { | 11563 bool AbstractType::IsInstantiated(GrowableObjectArray* trail) const { |
11558 // AbstractType is an abstract class. | 11564 // AbstractType is an abstract class. |
11559 UNREACHABLE(); | 11565 UNREACHABLE(); |
11560 return false; | 11566 return false; |
11561 } | 11567 } |
11562 | 11568 |
11563 | 11569 |
11564 bool AbstractType::IsFinalized() const { | 11570 bool AbstractType::IsFinalized() const { |
11565 // AbstractType is an abstract class. | 11571 // AbstractType is an abstract class. |
11566 UNREACHABLE(); | 11572 UNREACHABLE(); |
11567 return false; | 11573 return false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11602 return LanguageError::null(); | 11608 return LanguageError::null(); |
11603 } | 11609 } |
11604 | 11610 |
11605 | 11611 |
11606 void AbstractType::set_error(const LanguageError& value) const { | 11612 void AbstractType::set_error(const LanguageError& value) const { |
11607 // AbstractType is an abstract class. | 11613 // AbstractType is an abstract class. |
11608 UNREACHABLE(); | 11614 UNREACHABLE(); |
11609 } | 11615 } |
11610 | 11616 |
11611 | 11617 |
11612 bool AbstractType::Equals(const Instance& other) const { | 11618 bool AbstractType::IsEquivalent(const Instance& other, |
11619 GrowableObjectArray* trail) const { | |
11613 // AbstractType is an abstract class. | 11620 // AbstractType is an abstract class. |
11614 UNREACHABLE(); | 11621 UNREACHABLE(); |
11615 return false; | 11622 return false; |
11616 } | 11623 } |
11617 | 11624 |
11618 | 11625 |
11619 RawAbstractType* AbstractType::InstantiateFrom( | 11626 RawAbstractType* AbstractType::InstantiateFrom( |
11620 const AbstractTypeArguments& instantiator_type_arguments, | 11627 const AbstractTypeArguments& instantiator_type_arguments, |
11621 Error* bound_error) const { | 11628 Error* bound_error, |
11629 GrowableObjectArray* trail) const { | |
11622 // AbstractType is an abstract class. | 11630 // AbstractType is an abstract class. |
11623 UNREACHABLE(); | 11631 UNREACHABLE(); |
11624 return NULL; | 11632 return NULL; |
11625 } | 11633 } |
11626 | 11634 |
11627 | 11635 |
11628 RawAbstractType* AbstractType::CloneUnfinalized() const { | 11636 RawAbstractType* AbstractType::CloneUnfinalized() const { |
11629 // AbstractType is an abstract class. | 11637 // AbstractType is an abstract class. |
11630 UNREACHABLE(); | 11638 UNREACHABLE(); |
11631 return NULL; | 11639 return NULL; |
11632 } | 11640 } |
11633 | 11641 |
11634 | 11642 |
11635 RawAbstractType* AbstractType::Canonicalize() const { | 11643 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const { |
11636 // AbstractType is an abstract class. | 11644 // AbstractType is an abstract class. |
11637 UNREACHABLE(); | 11645 UNREACHABLE(); |
11638 return NULL; | 11646 return NULL; |
11639 } | 11647 } |
11640 | 11648 |
11641 | 11649 |
11642 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 11650 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
11643 if (IsBoundedType()) { | 11651 if (IsBoundedType()) { |
11644 const AbstractType& type = AbstractType::Handle( | 11652 const AbstractType& type = AbstractType::Handle( |
11645 BoundedType::Cast(*this).type()); | 11653 BoundedType::Cast(*this).type()); |
11646 if (name_visibility == kUserVisibleName) { | 11654 if (name_visibility == kUserVisibleName) { |
11647 return type.BuildName(kUserVisibleName); | 11655 return type.BuildName(kUserVisibleName); |
11648 } | 11656 } |
11649 String& type_name = String::Handle(type.BuildName(kInternalName)); | 11657 String& type_name = String::Handle(type.BuildName(kInternalName)); |
11650 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); | 11658 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); |
11651 // Building the bound name may lead into cycles. | 11659 // Build the bound name without causing divergence. |
11652 const AbstractType& bound = AbstractType::Handle( | 11660 const AbstractType& bound = AbstractType::Handle( |
11653 BoundedType::Cast(*this).bound()); | 11661 BoundedType::Cast(*this).bound()); |
11654 String& bound_name = String::Handle(); | 11662 String& bound_name = String::Handle(); |
11655 if (bound.IsTypeParameter()) { | 11663 if (bound.IsTypeParameter()) { |
11656 bound_name = TypeParameter::Cast(bound).name(); | 11664 bound_name = TypeParameter::Cast(bound).name(); |
11657 } else if (bound.IsType()) { | 11665 } else if (bound.IsType()) { |
11658 const Class& cls = Class::Handle(Type::Cast(bound).type_class()); | 11666 const Class& cls = Class::Handle(Type::Cast(bound).type_class()); |
11659 bound_name = cls.Name(); | 11667 bound_name = cls.Name(); |
11660 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) { | 11668 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) { |
11661 bound_name = String::Concat(bound_name, Symbols::OptimizedOut()); | 11669 bound_name = String::Concat(bound_name, Symbols::OptimizedOut()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11702 // The actual type argument vector can be longer than necessary, because | 11710 // The actual type argument vector can be longer than necessary, because |
11703 // of type optimizations. | 11711 // of type optimizations. |
11704 if (IsFinalized() && cls.is_type_finalized()) { | 11712 if (IsFinalized() && cls.is_type_finalized()) { |
11705 first_type_param_index = cls.NumTypeArguments() - num_type_params; | 11713 first_type_param_index = cls.NumTypeArguments() - num_type_params; |
11706 } else { | 11714 } else { |
11707 first_type_param_index = num_args - num_type_params; | 11715 first_type_param_index = num_args - num_type_params; |
11708 } | 11716 } |
11709 } | 11717 } |
11710 if (cls.IsSignatureClass()) { | 11718 if (cls.IsSignatureClass()) { |
11711 // We may be reporting an error about a malformed function type. In that | 11719 // We may be reporting an error about a malformed function type. In that |
11712 // case, avoid instantiating the signature, since it may lead to cycles. | 11720 // case, avoid instantiating the signature, since it may cause divergence. |
11713 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { | 11721 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { |
11714 return class_name.raw(); | 11722 return class_name.raw(); |
11715 } | 11723 } |
11716 // In order to avoid cycles, print the name of a typedef (non-canonical | 11724 // To avoid divergence, print the name of a typedef (non-canonical |
11717 // signature class) as a regular, possibly parameterized, class. | 11725 // signature class) as a regular, possibly parameterized, class. |
11718 if (cls.IsCanonicalSignatureClass()) { | 11726 if (cls.IsCanonicalSignatureClass()) { |
11719 const Function& signature_function = Function::Handle( | 11727 const Function& signature_function = Function::Handle( |
11720 cls.signature_function()); | 11728 cls.signature_function()); |
11721 // Signature classes have no super type, however, they take as many | 11729 // Signature classes have no super type, however, they take as many |
11722 // type arguments as the owner class of their signature function (if it | 11730 // type arguments as the owner class of their signature function (if it |
11723 // is non static and generic, see Class::NumTypeArguments()). Therefore, | 11731 // is non static and generic, see Class::NumTypeArguments()). Therefore, |
11724 // first_type_param_index may be greater than 0 here. | 11732 // first_type_param_index may be greater than 0 here. |
11725 return signature_function.InstantiatedSignatureFrom(args, | 11733 return signature_function.InstantiatedSignatureFrom(args, |
11726 name_visibility); | 11734 name_visibility); |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12111 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); | 12119 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); |
12112 #endif | 12120 #endif |
12113 } | 12121 } |
12114 | 12122 |
12115 | 12123 |
12116 RawAbstractTypeArguments* Type::arguments() const { | 12124 RawAbstractTypeArguments* Type::arguments() const { |
12117 return raw_ptr()->arguments_; | 12125 return raw_ptr()->arguments_; |
12118 } | 12126 } |
12119 | 12127 |
12120 | 12128 |
12121 bool Type::IsInstantiated() const { | 12129 bool Type::IsInstantiated(GrowableObjectArray* trail) const { |
12122 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | 12130 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |
12123 return true; | 12131 return true; |
12124 } | 12132 } |
12125 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { | 12133 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { |
12126 return false; | 12134 return false; |
12127 } | 12135 } |
12128 const AbstractTypeArguments& args = | 12136 const AbstractTypeArguments& args = |
12129 AbstractTypeArguments::Handle(arguments()); | 12137 AbstractTypeArguments::Handle(arguments()); |
12130 return args.IsNull() || args.IsInstantiated(); | 12138 return args.IsNull() || args.IsInstantiated(trail); |
12131 } | 12139 } |
12132 | 12140 |
12133 | 12141 |
12134 RawAbstractType* Type::InstantiateFrom( | 12142 RawAbstractType* Type::InstantiateFrom( |
12135 const AbstractTypeArguments& instantiator_type_arguments, | 12143 const AbstractTypeArguments& instantiator_type_arguments, |
12136 Error* bound_error) const { | 12144 Error* bound_error, |
12145 GrowableObjectArray* trail) const { | |
12137 ASSERT(IsFinalized() || IsBeingFinalized()); | 12146 ASSERT(IsFinalized() || IsBeingFinalized()); |
12138 ASSERT(!IsInstantiated()); | 12147 ASSERT(!IsInstantiated()); |
12139 // Return the uninstantiated type unchanged if malformed. No copy needed. | 12148 // Return the uninstantiated type unchanged if malformed. No copy needed. |
12140 if (IsMalformed()) { | 12149 if (IsMalformed()) { |
12141 return raw(); | 12150 return raw(); |
12142 } | 12151 } |
12143 AbstractTypeArguments& type_arguments = | 12152 AbstractTypeArguments& type_arguments = |
12144 AbstractTypeArguments::Handle(arguments()); | 12153 AbstractTypeArguments::Handle(arguments()); |
12145 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | 12154 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
12146 bound_error); | 12155 bound_error, |
12156 trail); | |
12147 // Note that the type class has to be resolved at this time, but not | 12157 // Note that the type class has to be resolved at this time, but not |
12148 // necessarily finalized yet. We may be checking bounds at compile time. | 12158 // necessarily finalized yet. We may be checking bounds at compile time. |
12149 const Class& cls = Class::Handle(type_class()); | 12159 const Class& cls = Class::Handle(type_class()); |
12150 // This uninstantiated type is not modified, as it can be instantiated | 12160 // This uninstantiated type is not modified, as it can be instantiated |
12151 // with different instantiators. | 12161 // with different instantiators. |
12152 Type& instantiated_type = Type::Handle( | 12162 Type& instantiated_type = Type::Handle( |
12153 Type::New(cls, type_arguments, token_pos())); | 12163 Type::New(cls, type_arguments, token_pos())); |
12154 ASSERT(type_arguments.IsNull() || | 12164 ASSERT(type_arguments.IsNull() || |
12155 (type_arguments.Length() == cls.NumTypeArguments())); | 12165 (type_arguments.Length() == cls.NumTypeArguments())); |
12156 instantiated_type.SetIsFinalized(); | 12166 instantiated_type.SetIsFinalized(); |
12157 return instantiated_type.raw(); | 12167 return instantiated_type.raw(); |
12158 } | 12168 } |
12159 | 12169 |
12160 | 12170 |
12161 bool Type::Equals(const Instance& other) const { | 12171 bool Type::IsEquivalent(const Instance& other, |
12172 GrowableObjectArray* trail) const { | |
12162 ASSERT(!IsNull()); | 12173 ASSERT(!IsNull()); |
12163 if (raw() == other.raw()) { | 12174 if (raw() == other.raw()) { |
12164 return true; | 12175 return true; |
12165 } | 12176 } |
12166 if (other.IsTypeRef()) { | 12177 if (other.IsTypeRef()) { |
12167 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | 12178 // Unfold right hand type. Divergence is controlled by left hand type. |
12168 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | 12179 const AbstractType& other_ref_type = AbstractType::Handle( |
12180 TypeRef::Cast(other).type()); | |
12181 ASSERT(!other_ref_type.IsTypeRef()); | |
12182 return IsEquivalent(other_ref_type, trail); | |
12169 } | 12183 } |
12170 if (!other.IsType()) { | 12184 if (!other.IsType()) { |
12171 return false; | 12185 return false; |
12172 } | 12186 } |
12173 const Type& other_type = Type::Cast(other); | 12187 const Type& other_type = Type::Cast(other); |
12174 ASSERT(IsResolved() && other_type.IsResolved()); | 12188 ASSERT(IsResolved() && other_type.IsResolved()); |
12175 if (IsMalformed() || other_type.IsMalformed()) { | 12189 if (IsMalformed() || other_type.IsMalformed()) { |
12176 return false; | 12190 return false; |
12177 } | 12191 } |
12178 if (type_class() != other_type.type_class()) { | 12192 if (type_class() != other_type.type_class()) { |
(...skipping 23 matching lines...) Expand all Loading... | |
12202 if (other_type_args.IsNull()) { | 12216 if (other_type_args.IsNull()) { |
12203 return type_args.IsRaw(from_index, num_type_params); | 12217 return type_args.IsRaw(from_index, num_type_params); |
12204 } | 12218 } |
12205 ASSERT(type_args.Length() >= (from_index + num_type_params)); | 12219 ASSERT(type_args.Length() >= (from_index + num_type_params)); |
12206 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); | 12220 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); |
12207 AbstractType& type_arg = AbstractType::Handle(); | 12221 AbstractType& type_arg = AbstractType::Handle(); |
12208 AbstractType& other_type_arg = AbstractType::Handle(); | 12222 AbstractType& other_type_arg = AbstractType::Handle(); |
12209 for (intptr_t i = 0; i < num_type_params; i++) { | 12223 for (intptr_t i = 0; i < num_type_params; i++) { |
12210 type_arg = type_args.TypeAt(from_index + i); | 12224 type_arg = type_args.TypeAt(from_index + i); |
12211 other_type_arg = other_type_args.TypeAt(from_index + i); | 12225 other_type_arg = other_type_args.TypeAt(from_index + i); |
12212 if (!type_arg.Equals(other_type_arg)) { | 12226 if (!type_arg.IsEquivalent(other_type_arg, trail)) { |
12213 return false; | 12227 return false; |
12214 } | 12228 } |
12215 } | 12229 } |
12216 return true; | 12230 return true; |
12217 } | 12231 } |
12218 | 12232 |
12219 | 12233 |
12220 RawAbstractType* Type::CloneUnfinalized() const { | 12234 RawAbstractType* Type::CloneUnfinalized() const { |
12221 ASSERT(IsResolved()); | 12235 ASSERT(IsResolved()); |
12222 if (IsFinalized()) { | 12236 if (IsFinalized()) { |
12223 return raw(); | 12237 return raw(); |
12224 } | 12238 } |
12225 ASSERT(!IsMalformed()); // Malformed types are finalized. | 12239 ASSERT(!IsMalformed()); // Malformed types are finalized. |
12226 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. | 12240 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. |
12227 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); | 12241 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); |
12228 type_args = type_args.CloneUnfinalized(); | 12242 type_args = type_args.CloneUnfinalized(); |
12229 const Class& type_cls = Class::Handle(type_class()); | 12243 const Class& type_cls = Class::Handle(type_class()); |
12230 return Type::New(type_cls, type_args, token_pos()); | 12244 return Type::New(type_cls, type_args, token_pos()); |
12231 } | 12245 } |
12232 | 12246 |
12233 | 12247 |
12234 RawAbstractType* Type::Canonicalize() const { | 12248 RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const { |
12235 ASSERT(IsFinalized()); | 12249 ASSERT(IsFinalized()); |
12236 if (IsCanonical() || IsMalformed()) { | 12250 if (IsCanonical() || IsMalformed()) { |
12237 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); | 12251 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); |
12238 return this->raw(); | 12252 return this->raw(); |
12239 } | 12253 } |
12240 Isolate* isolate = Isolate::Current(); | 12254 Isolate* isolate = Isolate::Current(); |
12241 Type& type = Type::Handle(isolate); | 12255 Type& type = Type::Handle(isolate); |
12242 const Class& cls = Class::Handle(isolate, type_class()); | 12256 const Class& cls = Class::Handle(isolate, type_class()); |
12243 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) { | 12257 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) { |
12244 return Object::dynamic_type(); | 12258 return Object::dynamic_type(); |
(...skipping 30 matching lines...) Expand all Loading... | |
12275 ASSERT(type.IsFinalized()); | 12289 ASSERT(type.IsFinalized()); |
12276 if (this->Equals(type)) { | 12290 if (this->Equals(type)) { |
12277 return type.raw(); | 12291 return type.raw(); |
12278 } | 12292 } |
12279 index++; | 12293 index++; |
12280 } | 12294 } |
12281 // Canonicalize the type arguments. | 12295 // Canonicalize the type arguments. |
12282 AbstractTypeArguments& type_args = | 12296 AbstractTypeArguments& type_args = |
12283 AbstractTypeArguments::Handle(isolate, arguments()); | 12297 AbstractTypeArguments::Handle(isolate, arguments()); |
12284 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments())); | 12298 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments())); |
12285 type_args = type_args.Canonicalize(); | 12299 type_args = type_args.Canonicalize(trail); |
12286 set_arguments(type_args); | 12300 set_arguments(type_args); |
12287 // The type needs to be added to the list. Grow the list if it is full. | 12301 // The type needs to be added to the list. Grow the list if it is full. |
12288 if (index == canonical_types_len) { | 12302 if (index == canonical_types_len) { |
12289 const intptr_t kLengthIncrement = 2; // Raw and parameterized. | 12303 const intptr_t kLengthIncrement = 2; // Raw and parameterized. |
12290 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; | 12304 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; |
12291 const Array& new_canonical_types = Array::Handle( | 12305 const Array& new_canonical_types = Array::Handle( |
12292 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); | 12306 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); |
12293 cls.set_canonical_types(new_canonical_types); | 12307 cls.set_canonical_types(new_canonical_types); |
12294 new_canonical_types.SetAt(index, *this); | 12308 new_canonical_types.SetAt(index, *this); |
12295 } else { | 12309 } else { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12413 return "Unresolved Type"; | 12427 return "Unresolved Type"; |
12414 } | 12428 } |
12415 } | 12429 } |
12416 | 12430 |
12417 | 12431 |
12418 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { | 12432 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { |
12419 JSONObject jsobj(stream); | 12433 JSONObject jsobj(stream); |
12420 } | 12434 } |
12421 | 12435 |
12422 | 12436 |
12423 bool TypeRef::IsInstantiated() const { | 12437 bool TypeRef::IsInstantiated(GrowableObjectArray* trail) const { |
12424 if (is_being_checked()) { | 12438 if (TestAndAddToTrail(&trail)) { |
12425 return true; | 12439 return true; |
12426 } | 12440 } |
12427 set_is_being_checked(true); | 12441 return AbstractType::Handle(type()).IsInstantiated(trail); |
12428 const bool result = AbstractType::Handle(type()).IsInstantiated(); | |
12429 set_is_being_checked(false); | |
12430 return result; | |
12431 } | 12442 } |
12432 | 12443 |
12433 | 12444 |
12434 bool TypeRef::Equals(const Instance& other) const { | 12445 bool TypeRef::IsEquivalent(const Instance& other, |
12435 // TODO(regis): Use trail instead of mark bit. | 12446 GrowableObjectArray* trail) const { |
12436 if (raw() == other.raw()) { | 12447 if (raw() == other.raw()) { |
12437 return true; | 12448 return true; |
12438 } | 12449 } |
12439 if (is_being_checked()) { | 12450 if (TestAndAddBuddyToTrail(&trail, other)) { |
12440 return true; | 12451 return true; |
12441 } | 12452 } |
12442 set_is_being_checked(true); | 12453 return AbstractType::Handle(type()).IsEquivalent(other, trail); |
12443 const bool result = AbstractType::Handle(type()).Equals(other); | |
12444 set_is_being_checked(false); | |
12445 return result; | |
12446 } | 12454 } |
12447 | 12455 |
12448 | 12456 |
12449 RawAbstractType* TypeRef::InstantiateFrom( | 12457 RawAbstractType* TypeRef::InstantiateFrom( |
12450 const AbstractTypeArguments& instantiator_type_arguments, | 12458 const AbstractTypeArguments& instantiator_type_arguments, |
12451 Error* bound_error) const { | 12459 Error* bound_error, |
12460 GrowableObjectArray* trail) const { | |
12461 TypeRef& instantiated_type_ref = TypeRef::Handle(); | |
12462 instantiated_type_ref ^= BuddyInTrail(trail); | |
12463 if (!instantiated_type_ref.IsNull()) { | |
12464 return instantiated_type_ref.raw(); | |
12465 } | |
12466 instantiated_type_ref = TypeRef::New(Type::Handle(Type::DynamicType())); | |
12467 AddBuddyToTrail(&trail, instantiated_type_ref); | |
12452 const AbstractType& ref_type = AbstractType::Handle(type()); | 12468 const AbstractType& ref_type = AbstractType::Handle(type()); |
12453 // TODO(regis): Use trail instead of mark bit plus temporary redirection, | |
12454 // because it could be marked for another reason. | |
12455 if (is_being_checked()) { | |
12456 ASSERT(ref_type.IsTypeRef()); | |
12457 return ref_type.raw(); | |
12458 } | |
12459 set_is_being_checked(true); | |
12460 ASSERT(!ref_type.IsTypeRef()); | 12469 ASSERT(!ref_type.IsTypeRef()); |
12461 const TypeRef& instantiated_type_ref = TypeRef::Handle( | |
12462 TypeRef::New(ref_type)); | |
12463 // TODO(regis): instantiated_type_ref should be stored in the trail instead. | |
12464 set_type(instantiated_type_ref); | |
12465 const AbstractType& instantiated_ref_type = AbstractType::Handle( | 12470 const AbstractType& instantiated_ref_type = AbstractType::Handle( |
12466 ref_type.InstantiateFrom(instantiator_type_arguments, bound_error)); | 12471 ref_type.InstantiateFrom(instantiator_type_arguments, |
12472 bound_error, | |
12473 trail)); | |
12467 instantiated_type_ref.set_type(instantiated_ref_type); | 12474 instantiated_type_ref.set_type(instantiated_ref_type); |
12468 set_type(ref_type); | |
12469 set_is_being_checked(false); | |
12470 return instantiated_type_ref.raw(); | 12475 return instantiated_type_ref.raw(); |
12471 } | 12476 } |
12472 | 12477 |
12473 | 12478 |
12474 void TypeRef::set_type(const AbstractType& value) const { | 12479 void TypeRef::set_type(const AbstractType& value) const { |
12475 ASSERT(value.HasResolvedTypeClass()); | 12480 ASSERT(value.HasResolvedTypeClass()); |
12476 StorePointer(&raw_ptr()->type_, value.raw()); | 12481 StorePointer(&raw_ptr()->type_, value.raw()); |
12477 } | 12482 } |
12478 | 12483 |
12479 | 12484 |
12480 void TypeRef::set_is_being_checked(bool value) const { | 12485 // A TypeRef cannot be canonical by definition. Only its referenced type can be. |
12481 raw_ptr()->is_being_checked_ = value; | |
12482 } | |
12483 | |
12484 | |
12485 // This function only canonicalizes the referenced type, but not the TypeRef | |
12486 // itself, since it cannot be canonical by definition. | |
12487 // Consider the type Derived, where class Derived extends Base<Derived>. | 12486 // Consider the type Derived, where class Derived extends Base<Derived>. |
12488 // The first type argument of its flattened type argument vector is Derived, | 12487 // The first type argument of its flattened type argument vector is Derived, |
12489 // i.e. itself, but pointer equality is not possible. | 12488 // i.e. itself, but pointer equality is not possible. |
12490 RawAbstractType* TypeRef::Canonicalize() const { | 12489 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const { |
12491 // TODO(regis): Use trail, not mark bit. | 12490 if (TestAndAddToTrail(&trail)) { |
12492 if (is_being_checked()) { | |
12493 return raw(); | 12491 return raw(); |
12494 } | 12492 } |
12495 set_is_being_checked(true); | |
12496 AbstractType& ref_type = AbstractType::Handle(type()); | 12493 AbstractType& ref_type = AbstractType::Handle(type()); |
12497 ASSERT(!ref_type.IsTypeRef()); | 12494 ref_type = ref_type.Canonicalize(trail); |
12498 ref_type = ref_type.Canonicalize(); | |
12499 set_type(ref_type); | 12495 set_type(ref_type); |
12500 // No need to call SetCanonical(), since a TypeRef cannot be canonical by | 12496 return raw(); |
12501 // definition. | |
12502 set_is_being_checked(false); | |
12503 // We return the referenced type instead of the TypeRef in order to provide | |
12504 // pointer equality in simple cases, e.g. in language/f_bounded_equality_test. | |
12505 return ref_type.raw(); | |
12506 } | 12497 } |
12507 | 12498 |
12508 | 12499 |
12509 intptr_t TypeRef::Hash() const { | 12500 intptr_t TypeRef::Hash() const { |
12510 // TODO(regis): Use trail and hash of referenced type. | 12501 // Do not calculate the hash of the referenced type to avoid divergence. |
12511 // Do not calculate the hash of the referenced type to avoid cycles. | |
12512 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); | 12502 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); |
12513 return FinalizeHash(result); | 12503 return FinalizeHash(result); |
12514 } | 12504 } |
12515 | 12505 |
12516 | 12506 |
12507 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const { | |
12508 if (*trail == NULL) { | |
12509 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); | |
12510 } else { | |
12511 const intptr_t len = (*trail)->Length(); | |
12512 for (intptr_t i = 0; i < len; i++) { | |
12513 if ((*trail)->At(i) == this->raw()) { | |
12514 return true; | |
12515 } | |
12516 } | |
12517 } | |
12518 (*trail)->Add(*this); | |
12519 return false; | |
12520 } | |
12521 | |
12522 | |
12523 bool TypeRef::TestAndAddBuddyToTrail(GrowableObjectArray** trail, | |
12524 const Object& buddy) const { | |
12525 if (*trail == NULL) { | |
12526 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); | |
12527 } else { | |
12528 const intptr_t len = (*trail)->Length(); | |
12529 ASSERT((len % 2) == 0); | |
12530 for (intptr_t i = 0; i < len; i += 2) { | |
12531 if (((*trail)->At(i) == this->raw()) && | |
12532 ((*trail)->At(i + 1) == buddy.raw())) { | |
12533 return true; | |
12534 } | |
12535 } | |
12536 } | |
12537 (*trail)->Add(*this); | |
12538 (*trail)->Add(buddy); | |
siva
2013/12/20 19:35:10
The code in this function seems to imply that a re
regis
2014/01/07 20:26:27
I renamed the other function AddOnlyBuddyToTrail.
| |
12539 return false; | |
12540 } | |
12541 | |
12542 | |
12543 RawObject* TypeRef::BuddyInTrail(GrowableObjectArray* trail) const { | |
12544 if (trail == NULL) { | |
12545 return Object::null(); | |
12546 } | |
12547 const intptr_t len = trail->Length(); | |
12548 ASSERT((len % 2) == 0); | |
12549 for (intptr_t i = 0; i < len; i += 2) { | |
12550 if (trail->At(i) == this->raw()) { | |
siva
2013/12/20 19:35:10
Should there be an assert here:
ASSERT(trail->At(i
regis
2014/01/07 20:26:27
Done.
| |
12551 return trail->At(i + 1); | |
12552 } | |
12553 } | |
12554 return Object::null(); | |
12555 } | |
12556 | |
12557 | |
12558 void TypeRef::AddBuddyToTrail(GrowableObjectArray** trail, | |
12559 const Object& buddy) const { | |
12560 if (*trail == NULL) { | |
12561 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); | |
12562 } else { | |
12563 ASSERT(BuddyInTrail(*trail) == Object::null()); | |
12564 } | |
12565 (*trail)->Add(*this); | |
12566 (*trail)->Add(buddy); | |
12567 } | |
12568 | |
12569 | |
12517 RawTypeRef* TypeRef::New() { | 12570 RawTypeRef* TypeRef::New() { |
12518 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); | 12571 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); |
12519 RawObject* raw = Object::Allocate(TypeRef::kClassId, | 12572 RawObject* raw = Object::Allocate(TypeRef::kClassId, |
12520 TypeRef::InstanceSize(), | 12573 TypeRef::InstanceSize(), |
12521 Heap::kOld); | 12574 Heap::kOld); |
12522 return reinterpret_cast<RawTypeRef*>(raw); | 12575 return reinterpret_cast<RawTypeRef*>(raw); |
12523 } | 12576 } |
12524 | 12577 |
12525 | 12578 |
12526 RawTypeRef* TypeRef::New(const AbstractType& type) { | 12579 RawTypeRef* TypeRef::New(const AbstractType& type) { |
12527 const TypeRef& result = TypeRef::Handle(TypeRef::New()); | 12580 const TypeRef& result = TypeRef::Handle(TypeRef::New()); |
12528 result.set_type(type); | 12581 result.set_type(type); |
12529 result.set_is_being_checked(false); | |
12530 return result.raw(); | 12582 return result.raw(); |
12531 } | 12583 } |
12532 | 12584 |
12533 | 12585 |
12534 const char* TypeRef::ToCString() const { | 12586 const char* TypeRef::ToCString() const { |
12535 const char* format = "TypeRef: %s%s"; | 12587 const char* format = "TypeRef: %s%s"; |
12536 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( | 12588 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( |
12537 type()).type_class()).Name()).ToCString(); | 12589 type()).type_class()).Name()).ToCString(); |
12538 const char* args_cstr = (AbstractType::Handle( | 12590 const char* args_cstr = (AbstractType::Handle( |
12539 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; | 12591 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; |
12540 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; | 12592 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; |
12541 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 12593 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
12542 OS::SNPrint(chars, len, format, type_cstr, args_cstr); | 12594 OS::SNPrint(chars, len, format, type_cstr, args_cstr); |
12543 return chars; | 12595 return chars; |
12544 } | 12596 } |
12545 | 12597 |
12546 | 12598 |
12547 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { | 12599 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { |
12548 JSONObject jsobj(stream); | 12600 JSONObject jsobj(stream); |
12549 } | 12601 } |
12550 | 12602 |
12551 | 12603 |
12552 void TypeParameter::set_is_finalized() const { | 12604 void TypeParameter::set_is_finalized() const { |
12553 ASSERT(!IsFinalized()); | 12605 ASSERT(!IsFinalized()); |
12554 set_type_state(RawTypeParameter::kFinalizedUninstantiated); | 12606 set_type_state(RawTypeParameter::kFinalizedUninstantiated); |
12555 } | 12607 } |
12556 | 12608 |
12557 | 12609 |
12558 bool TypeParameter::Equals(const Instance& other) const { | 12610 bool TypeParameter::IsEquivalent(const Instance& other, |
12611 GrowableObjectArray* trail) const { | |
12559 if (raw() == other.raw()) { | 12612 if (raw() == other.raw()) { |
12560 return true; | 12613 return true; |
12561 } | 12614 } |
12562 if (other.IsTypeRef()) { | 12615 if (other.IsTypeRef()) { |
12563 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | 12616 // Unfold right hand type. Divergence is controlled by left hand type. |
12564 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | 12617 const AbstractType& other_ref_type = AbstractType::Handle( |
12618 TypeRef::Cast(other).type()); | |
12619 ASSERT(!other_ref_type.IsTypeRef()); | |
12620 return IsEquivalent(other_ref_type, trail); | |
12565 } | 12621 } |
12566 if (!other.IsTypeParameter()) { | 12622 if (!other.IsTypeParameter()) { |
12567 return false; | 12623 return false; |
12568 } | 12624 } |
12569 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 12625 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
12570 if (parameterized_class() != other_type_param.parameterized_class()) { | 12626 if (parameterized_class() != other_type_param.parameterized_class()) { |
12571 return false; | 12627 return false; |
12572 } | 12628 } |
12573 if (IsFinalized() == other_type_param.IsFinalized()) { | 12629 if (IsFinalized() == other_type_param.IsFinalized()) { |
12574 return index() == other_type_param.index(); | 12630 return index() == other_type_param.index(); |
(...skipping 20 matching lines...) Expand all Loading... | |
12595 } | 12651 } |
12596 | 12652 |
12597 | 12653 |
12598 void TypeParameter::set_bound(const AbstractType& value) const { | 12654 void TypeParameter::set_bound(const AbstractType& value) const { |
12599 StorePointer(&raw_ptr()->bound_, value.raw()); | 12655 StorePointer(&raw_ptr()->bound_, value.raw()); |
12600 } | 12656 } |
12601 | 12657 |
12602 | 12658 |
12603 RawAbstractType* TypeParameter::InstantiateFrom( | 12659 RawAbstractType* TypeParameter::InstantiateFrom( |
12604 const AbstractTypeArguments& instantiator_type_arguments, | 12660 const AbstractTypeArguments& instantiator_type_arguments, |
12605 Error* bound_error) const { | 12661 Error* bound_error, |
12662 GrowableObjectArray* trail) const { | |
12606 ASSERT(IsFinalized()); | 12663 ASSERT(IsFinalized()); |
12607 if (instantiator_type_arguments.IsNull()) { | 12664 if (instantiator_type_arguments.IsNull()) { |
12608 return Type::DynamicType(); | 12665 return Type::DynamicType(); |
12609 } | 12666 } |
12610 const AbstractType& type_arg = AbstractType::Handle( | 12667 const AbstractType& type_arg = AbstractType::Handle( |
12611 instantiator_type_arguments.TypeAt(index())); | 12668 instantiator_type_arguments.TypeAt(index())); |
12612 // There is no need to canonicalize the instantiated type parameter, since all | 12669 // There is no need to canonicalize the instantiated type parameter, since all |
12613 // type arguments are canonicalized at type finalization time. It would be too | 12670 // type arguments are canonicalized at type finalization time. It would be too |
12614 // early to canonicalize the returned type argument here, since instantiation | 12671 // early to canonicalize the returned type argument here, since instantiation |
12615 // not only happens at run time, but also during type finalization. | 12672 // not only happens at run time, but also during type finalization. |
12616 // However, if the type argument is a reference to a canonical type, we | |
12617 // return the referenced canonical type instead of the type reference to | |
12618 // provide pointer equality in some simple cases, e.g. in | |
12619 // language/f_bounded_equality_test. | |
12620 if (type_arg.IsTypeRef()) { | |
12621 const AbstractType& ref_type = AbstractType::Handle( | |
12622 TypeRef::Cast(type_arg).type()); | |
12623 if (ref_type.IsCanonical()) { | |
12624 return ref_type.raw(); | |
12625 } | |
12626 } | |
12627 return type_arg.raw(); | 12673 return type_arg.raw(); |
12628 } | 12674 } |
12629 | 12675 |
12630 | 12676 |
12631 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 12677 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
12632 const AbstractType& upper_bound, | 12678 const AbstractType& upper_bound, |
12633 Error* bound_error) const { | 12679 Error* bound_error) const { |
12634 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 12680 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
12635 ASSERT(bounded_type.IsFinalized()); | 12681 ASSERT(bounded_type.IsFinalized()); |
12636 ASSERT(upper_bound.IsFinalized()); | 12682 ASSERT(upper_bound.IsFinalized()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12683 index(), | 12729 index(), |
12684 String::Handle(name()), | 12730 String::Handle(name()), |
12685 AbstractType::Handle(bound()), | 12731 AbstractType::Handle(bound()), |
12686 token_pos()); | 12732 token_pos()); |
12687 } | 12733 } |
12688 | 12734 |
12689 | 12735 |
12690 intptr_t TypeParameter::Hash() const { | 12736 intptr_t TypeParameter::Hash() const { |
12691 ASSERT(IsFinalized()); | 12737 ASSERT(IsFinalized()); |
12692 uword result = Class::Handle(parameterized_class()).id(); | 12738 uword result = Class::Handle(parameterized_class()).id(); |
12693 // Do not include the hash of the bound, which could lead to cycles. | 12739 // No need to include the hash of the bound, since the type parameter is fully |
12740 // identified by its class and index. | |
12694 result <<= index(); | 12741 result <<= index(); |
12695 return FinalizeHash(result); | 12742 return FinalizeHash(result); |
12696 } | 12743 } |
12697 | 12744 |
12698 | 12745 |
12699 RawTypeParameter* TypeParameter::New() { | 12746 RawTypeParameter* TypeParameter::New() { |
12700 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != | 12747 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != |
12701 Class::null()); | 12748 Class::null()); |
12702 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 12749 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
12703 TypeParameter::InstanceSize(), | 12750 TypeParameter::InstanceSize(), |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12767 bool BoundedType::IsMalformedOrMalbounded() const { | 12814 bool BoundedType::IsMalformedOrMalbounded() const { |
12768 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); | 12815 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); |
12769 } | 12816 } |
12770 | 12817 |
12771 | 12818 |
12772 RawLanguageError* BoundedType::error() const { | 12819 RawLanguageError* BoundedType::error() const { |
12773 return AbstractType::Handle(type()).error(); | 12820 return AbstractType::Handle(type()).error(); |
12774 } | 12821 } |
12775 | 12822 |
12776 | 12823 |
12777 bool BoundedType::Equals(const Instance& other) const { | 12824 bool BoundedType::IsEquivalent(const Instance& other, |
12825 GrowableObjectArray* trail) const { | |
12778 // BoundedType are not canonicalized, because their bound may get finalized | 12826 // BoundedType are not canonicalized, because their bound may get finalized |
12779 // after the BoundedType is created and initialized. | 12827 // after the BoundedType is created and initialized. |
12780 if (raw() == other.raw()) { | 12828 if (raw() == other.raw()) { |
12781 return true; | 12829 return true; |
12782 } | 12830 } |
12783 if (other.IsTypeRef()) { | 12831 if (other.IsTypeRef()) { |
12784 // TODO(regis): Use trail. For now, we "unfold" the right hand type. | 12832 // Unfold right hand type. Divergence is controlled by left hand type. |
12785 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); | 12833 const AbstractType& other_ref_type = AbstractType::Handle( |
12834 TypeRef::Cast(other).type()); | |
12835 ASSERT(!other_ref_type.IsTypeRef()); | |
12836 return IsEquivalent(other_ref_type, trail); | |
12786 } | 12837 } |
12787 if (!other.IsBoundedType()) { | 12838 if (!other.IsBoundedType()) { |
12788 return false; | 12839 return false; |
12789 } | 12840 } |
12790 const BoundedType& other_bounded = BoundedType::Cast(other); | 12841 const BoundedType& other_bounded = BoundedType::Cast(other); |
12791 if (type_parameter() != other_bounded.type_parameter()) { | 12842 if (type_parameter() != other_bounded.type_parameter()) { |
12792 // Not a structural compare. | |
12793 // Note that a deep comparison of bounds could lead to cycles. | |
12794 return false; | 12843 return false; |
12795 } | 12844 } |
12796 const AbstractType& this_type = AbstractType::Handle(type()); | 12845 const AbstractType& this_type = AbstractType::Handle(type()); |
12797 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); | 12846 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); |
12798 if (!this_type.Equals(other_type)) { | 12847 if (!this_type.IsEquivalent(other_type, trail)) { |
12799 return false; | 12848 return false; |
12800 } | 12849 } |
12801 const AbstractType& this_bound = AbstractType::Handle(bound()); | 12850 const AbstractType& this_bound = AbstractType::Handle(bound()); |
12802 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); | 12851 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |
12803 return this_bound.IsFinalized() && | 12852 return this_bound.IsFinalized() && |
12804 other_bound.IsFinalized() && | 12853 other_bound.IsFinalized() && |
12805 this_bound.Equals(other_bound); | 12854 this_bound.Equals(other_bound); // Different graph, do not pass trail. |
12806 } | 12855 } |
12807 | 12856 |
12808 | 12857 |
12809 void BoundedType::set_type(const AbstractType& value) const { | 12858 void BoundedType::set_type(const AbstractType& value) const { |
12810 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); | 12859 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); |
12811 ASSERT(!value.IsMalformed()); | 12860 ASSERT(!value.IsMalformed()); |
12812 StorePointer(&raw_ptr()->type_, value.raw()); | 12861 StorePointer(&raw_ptr()->type_, value.raw()); |
12813 } | 12862 } |
12814 | 12863 |
12815 | 12864 |
12816 void BoundedType::set_bound(const AbstractType& value) const { | 12865 void BoundedType::set_bound(const AbstractType& value) const { |
12817 // The bound may still be unfinalized because of legal cycles. | 12866 // The bound may still be unfinalized because of legal cycles. |
12818 // It must be finalized before it is checked at run time, though. | 12867 // It must be finalized before it is checked at run time, though. |
12819 StorePointer(&raw_ptr()->bound_, value.raw()); | 12868 StorePointer(&raw_ptr()->bound_, value.raw()); |
12820 } | 12869 } |
12821 | 12870 |
12822 | 12871 |
12823 void BoundedType::set_type_parameter(const TypeParameter& value) const { | 12872 void BoundedType::set_type_parameter(const TypeParameter& value) const { |
12824 // A null type parameter is set when marking a type malformed because of a | 12873 // A null type parameter is set when marking a type malformed because of a |
12825 // bound error at compile time. | 12874 // bound error at compile time. |
12826 ASSERT(value.IsNull() || value.IsFinalized()); | 12875 ASSERT(value.IsNull() || value.IsFinalized()); |
12827 StorePointer(&raw_ptr()->type_parameter_, value.raw()); | 12876 StorePointer(&raw_ptr()->type_parameter_, value.raw()); |
12828 } | 12877 } |
12829 | 12878 |
12830 | 12879 |
12831 void BoundedType::set_is_being_checked(bool value) const { | |
12832 raw_ptr()->is_being_checked_ = value; | |
12833 } | |
12834 | |
12835 | |
12836 RawAbstractType* BoundedType::InstantiateFrom( | 12880 RawAbstractType* BoundedType::InstantiateFrom( |
12837 const AbstractTypeArguments& instantiator_type_arguments, | 12881 const AbstractTypeArguments& instantiator_type_arguments, |
12838 Error* bound_error) const { | 12882 Error* bound_error, |
12883 GrowableObjectArray* trail) const { | |
12839 ASSERT(IsFinalized()); | 12884 ASSERT(IsFinalized()); |
12840 AbstractType& bounded_type = AbstractType::Handle(type()); | 12885 AbstractType& bounded_type = AbstractType::Handle(type()); |
12841 if (!bounded_type.IsInstantiated()) { | 12886 if (!bounded_type.IsInstantiated()) { |
12842 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, | 12887 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, |
12843 bound_error); | 12888 bound_error, |
12889 trail); | |
12844 } | 12890 } |
12845 if (FLAG_enable_type_checks && | 12891 if (FLAG_enable_type_checks && bound_error->IsNull()) { |
12846 bound_error->IsNull() && | |
12847 !is_being_checked()) { | |
12848 // Avoid endless recursion while checking and instantiating bound. | |
12849 set_is_being_checked(true); | |
12850 AbstractType& upper_bound = AbstractType::Handle(bound()); | 12892 AbstractType& upper_bound = AbstractType::Handle(bound()); |
12851 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); | 12893 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); |
12852 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 12894 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
12853 if (!upper_bound.IsInstantiated()) { | 12895 if (!upper_bound.IsInstantiated()) { |
12854 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, | 12896 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, |
12855 bound_error); | 12897 bound_error, |
12898 trail); | |
12856 } | 12899 } |
12857 if (bound_error->IsNull()) { | 12900 if (bound_error->IsNull()) { |
12858 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && | 12901 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && |
12859 bound_error->IsNull()) { | 12902 bound_error->IsNull()) { |
12860 // We cannot determine yet whether the bounded_type is below the | 12903 // We cannot determine yet whether the bounded_type is below the |
12861 // upper_bound, because one or both of them is still uninstantiated. | 12904 // upper_bound, because one or both of them is still uninstantiated. |
12862 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); | 12905 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); |
12863 // Postpone bound check by returning a new BoundedType with partially | 12906 // Postpone bound check by returning a new BoundedType with partially |
12864 // instantiated bounded_type and upper_bound, but keeping type_param. | 12907 // instantiated bounded_type and upper_bound, but keeping type_param. |
12865 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); | 12908 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); |
12866 } | 12909 } |
12867 } | 12910 } |
12868 set_is_being_checked(false); | |
12869 } | 12911 } |
12870 return bounded_type.raw(); | 12912 return bounded_type.raw(); |
12871 } | 12913 } |
12872 | 12914 |
12873 | 12915 |
12874 RawAbstractType* BoundedType::CloneUnfinalized() const { | 12916 RawAbstractType* BoundedType::CloneUnfinalized() const { |
12875 if (IsFinalized()) { | 12917 if (IsFinalized()) { |
12876 return raw(); | 12918 return raw(); |
12877 } | 12919 } |
12878 AbstractType& bounded_type = AbstractType::Handle(type()); | 12920 AbstractType& bounded_type = AbstractType::Handle(type()); |
12879 | 12921 |
12880 bounded_type = bounded_type.CloneUnfinalized(); | 12922 bounded_type = bounded_type.CloneUnfinalized(); |
12881 // No need to clone bound or type parameter, as they are not part of the | 12923 // No need to clone bound or type parameter, as they are not part of the |
12882 // finalization state of this bounded type. | 12924 // finalization state of this bounded type. |
12883 return BoundedType::New(bounded_type, | 12925 return BoundedType::New(bounded_type, |
12884 AbstractType::Handle(bound()), | 12926 AbstractType::Handle(bound()), |
12885 TypeParameter::Handle(type_parameter())); | 12927 TypeParameter::Handle(type_parameter())); |
12886 } | 12928 } |
12887 | 12929 |
12888 | 12930 |
12889 intptr_t BoundedType::Hash() const { | 12931 intptr_t BoundedType::Hash() const { |
12890 uword result = AbstractType::Handle(type()).Hash(); | 12932 uword result = AbstractType::Handle(type()).Hash(); |
12891 // Do not include the hash of the bound, which could lead to cycles. | 12933 // No need to include the hash of the bound, since the bound is defined by the |
12934 // type parameter (modulo instantiation state). | |
12892 result += TypeParameter::Handle(type_parameter()).Hash(); | 12935 result += TypeParameter::Handle(type_parameter()).Hash(); |
12893 return FinalizeHash(result); | 12936 return FinalizeHash(result); |
12894 } | 12937 } |
12895 | 12938 |
12896 | 12939 |
12897 RawBoundedType* BoundedType::New() { | 12940 RawBoundedType* BoundedType::New() { |
12898 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != | 12941 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != |
12899 Class::null()); | 12942 Class::null()); |
12900 RawObject* raw = Object::Allocate(BoundedType::kClassId, | 12943 RawObject* raw = Object::Allocate(BoundedType::kClassId, |
12901 BoundedType::InstanceSize(), | 12944 BoundedType::InstanceSize(), |
12902 Heap::kOld); | 12945 Heap::kOld); |
12903 return reinterpret_cast<RawBoundedType*>(raw); | 12946 return reinterpret_cast<RawBoundedType*>(raw); |
12904 } | 12947 } |
12905 | 12948 |
12906 | 12949 |
12907 RawBoundedType* BoundedType::New(const AbstractType& type, | 12950 RawBoundedType* BoundedType::New(const AbstractType& type, |
12908 const AbstractType& bound, | 12951 const AbstractType& bound, |
12909 const TypeParameter& type_parameter) { | 12952 const TypeParameter& type_parameter) { |
12910 const BoundedType& result = BoundedType::Handle(BoundedType::New()); | 12953 const BoundedType& result = BoundedType::Handle(BoundedType::New()); |
12911 result.set_type(type); | 12954 result.set_type(type); |
12912 result.set_bound(bound); | 12955 result.set_bound(bound); |
12913 result.set_type_parameter(type_parameter); | 12956 result.set_type_parameter(type_parameter); |
12914 result.set_is_being_checked(false); | |
12915 return result.raw(); | 12957 return result.raw(); |
12916 } | 12958 } |
12917 | 12959 |
12918 | 12960 |
12919 const char* BoundedType::ToCString() const { | 12961 const char* BoundedType::ToCString() const { |
12920 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; | 12962 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; |
12921 const char* type_cstr = String::Handle(AbstractType::Handle( | 12963 const char* type_cstr = String::Handle(AbstractType::Handle( |
12922 type()).Name()).ToCString(); | 12964 type()).Name()).ToCString(); |
12923 const char* bound_cstr = String::Handle(AbstractType::Handle( | 12965 const char* bound_cstr = String::Handle(AbstractType::Handle( |
12924 bound()).Name()).ToCString(); | 12966 bound()).Name()).ToCString(); |
(...skipping 3587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16512 return "_MirrorReference"; | 16554 return "_MirrorReference"; |
16513 } | 16555 } |
16514 | 16556 |
16515 | 16557 |
16516 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 16558 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
16517 Instance::PrintToJSONStream(stream, ref); | 16559 Instance::PrintToJSONStream(stream, ref); |
16518 } | 16560 } |
16519 | 16561 |
16520 | 16562 |
16521 } // namespace dart | 16563 } // namespace dart |
OLD | NEW |