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 3597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3608 // Type S is specified by this class parameterized with 'type_arguments', and | 3608 // Type S is specified by this class parameterized with 'type_arguments', and |
3609 // type T by class 'other' parameterized with 'other_type_arguments'. | 3609 // type T by class 'other' parameterized with 'other_type_arguments'. |
3610 // This class and class 'other' do not need to be finalized, however, they must | 3610 // This class and class 'other' do not need to be finalized, however, they must |
3611 // be resolved as well as their interfaces. | 3611 // be resolved as well as their interfaces. |
3612 bool Class::TypeTestNonRecursive(const Class& cls, | 3612 bool Class::TypeTestNonRecursive(const Class& cls, |
3613 Class::TypeTestKind test_kind, | 3613 Class::TypeTestKind test_kind, |
3614 const TypeArguments& type_arguments, | 3614 const TypeArguments& type_arguments, |
3615 const Class& other, | 3615 const Class& other, |
3616 const TypeArguments& other_type_arguments, | 3616 const TypeArguments& other_type_arguments, |
3617 Error* bound_error, | 3617 Error* bound_error, |
| 3618 TrailPtr bound_trail, |
3618 Heap::Space space) { | 3619 Heap::Space space) { |
3619 // Use the thsi object as if it was the receiver of this method, but instead | 3620 // Use the thsi object as if it was the receiver of this method, but instead |
3620 // of recursing reset it to the super class and loop. | 3621 // of recursing reset it to the super class and loop. |
3621 Zone* zone = Thread::Current()->zone(); | 3622 Zone* zone = Thread::Current()->zone(); |
3622 Class& thsi = Class::Handle(zone, cls.raw()); | 3623 Class& thsi = Class::Handle(zone, cls.raw()); |
3623 while (true) { | 3624 while (true) { |
3624 ASSERT(!thsi.IsVoidClass()); | 3625 ASSERT(!thsi.IsVoidClass()); |
3625 // Check for DynamicType. | 3626 // Check for DynamicType. |
3626 // Each occurrence of DynamicType in type T is interpreted as the dynamic | 3627 // Each occurrence of DynamicType in type T is interpreted as the dynamic |
3627 // type, a supertype of all types. | 3628 // type, a supertype of all types. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3666 // Other type can't be more specific than this one because for that | 3667 // Other type can't be more specific than this one because for that |
3667 // it would have to have all dynamic type arguments which is checked | 3668 // it would have to have all dynamic type arguments which is checked |
3668 // above. | 3669 // above. |
3669 return test_kind == Class::kIsSubtypeOf; | 3670 return test_kind == Class::kIsSubtypeOf; |
3670 } | 3671 } |
3671 return type_arguments.TypeTest(test_kind, | 3672 return type_arguments.TypeTest(test_kind, |
3672 other_type_arguments, | 3673 other_type_arguments, |
3673 from_index, | 3674 from_index, |
3674 num_type_params, | 3675 num_type_params, |
3675 bound_error, | 3676 bound_error, |
| 3677 bound_trail, |
3676 space); | 3678 space); |
3677 } | 3679 } |
3678 if (other.IsFunctionClass()) { | 3680 if (other.IsFunctionClass()) { |
3679 // Check if type S has a call() method. | 3681 // Check if type S has a call() method. |
3680 Function& function = | 3682 Function& function = |
3681 Function::Handle(zone, thsi.LookupDynamicFunction(Symbols::Call())); | 3683 Function::Handle(zone, thsi.LookupDynamicFunction(Symbols::Call())); |
3682 if (function.IsNull()) { | 3684 if (function.IsNull()) { |
3683 // Walk up the super_class chain. | 3685 // Walk up the super_class chain. |
3684 Class& cls = Class::Handle(zone, thsi.SuperClass()); | 3686 Class& cls = Class::Handle(zone, thsi.SuperClass()); |
3685 while (!cls.IsNull() && function.IsNull()) { | 3687 while (!cls.IsNull() && function.IsNull()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3726 // This type class implements an interface that is parameterized with | 3728 // This type class implements an interface that is parameterized with |
3727 // generic type(s), e.g. it implements List<T>. | 3729 // generic type(s), e.g. it implements List<T>. |
3728 // The uninstantiated type T must be instantiated using the type | 3730 // The uninstantiated type T must be instantiated using the type |
3729 // parameters of this type before performing the type test. | 3731 // parameters of this type before performing the type test. |
3730 // The type arguments of this type that are referred to by the type | 3732 // The type arguments of this type that are referred to by the type |
3731 // parameters of the interface are at the end of the type vector, | 3733 // parameters of the interface are at the end of the type vector, |
3732 // after the type arguments of the super type of this type. | 3734 // after the type arguments of the super type of this type. |
3733 // The index of the type parameters is adjusted upon finalization. | 3735 // The index of the type parameters is adjusted upon finalization. |
3734 error = Error::null(); | 3736 error = Error::null(); |
3735 interface_args = | 3737 interface_args = |
3736 interface_args.InstantiateFrom(type_arguments, &error, NULL, space); | 3738 interface_args.InstantiateFrom(type_arguments, |
| 3739 &error, |
| 3740 NULL, |
| 3741 bound_trail, |
| 3742 space); |
3737 if (!error.IsNull()) { | 3743 if (!error.IsNull()) { |
3738 // Return the first bound error to the caller if it requests it. | 3744 // Return the first bound error to the caller if it requests it. |
3739 if ((bound_error != NULL) && bound_error->IsNull()) { | 3745 if ((bound_error != NULL) && bound_error->IsNull()) { |
3740 *bound_error = error.raw(); | 3746 *bound_error = error.raw(); |
3741 } | 3747 } |
3742 continue; // Another interface may work better. | 3748 continue; // Another interface may work better. |
3743 } | 3749 } |
3744 } | 3750 } |
3745 if (interface_class.TypeTest(test_kind, | 3751 if (interface_class.TypeTest(test_kind, |
3746 interface_args, | 3752 interface_args, |
3747 other, | 3753 other, |
3748 other_type_arguments, | 3754 other_type_arguments, |
3749 bound_error, | 3755 bound_error, |
| 3756 bound_trail, |
3750 space)) { | 3757 space)) { |
3751 return true; | 3758 return true; |
3752 } | 3759 } |
3753 } | 3760 } |
3754 // "Recurse" up the class hierarchy until we have reached the top. | 3761 // "Recurse" up the class hierarchy until we have reached the top. |
3755 thsi = thsi.SuperClass(); | 3762 thsi = thsi.SuperClass(); |
3756 if (thsi.IsNull()) { | 3763 if (thsi.IsNull()) { |
3757 return false; | 3764 return false; |
3758 } | 3765 } |
3759 } | 3766 } |
3760 UNREACHABLE(); | 3767 UNREACHABLE(); |
3761 return false; | 3768 return false; |
3762 } | 3769 } |
3763 | 3770 |
3764 | 3771 |
3765 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. | 3772 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. |
3766 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. | 3773 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. |
3767 // Type S is specified by this class parameterized with 'type_arguments', and | 3774 // Type S is specified by this class parameterized with 'type_arguments', and |
3768 // type T by class 'other' parameterized with 'other_type_arguments'. | 3775 // type T by class 'other' parameterized with 'other_type_arguments'. |
3769 // This class and class 'other' do not need to be finalized, however, they must | 3776 // This class and class 'other' do not need to be finalized, however, they must |
3770 // be resolved as well as their interfaces. | 3777 // be resolved as well as their interfaces. |
3771 bool Class::TypeTest(TypeTestKind test_kind, | 3778 bool Class::TypeTest(TypeTestKind test_kind, |
3772 const TypeArguments& type_arguments, | 3779 const TypeArguments& type_arguments, |
3773 const Class& other, | 3780 const Class& other, |
3774 const TypeArguments& other_type_arguments, | 3781 const TypeArguments& other_type_arguments, |
3775 Error* bound_error, | 3782 Error* bound_error, |
| 3783 TrailPtr bound_trail, |
3776 Heap::Space space) const { | 3784 Heap::Space space) const { |
3777 return TypeTestNonRecursive(*this, | 3785 return TypeTestNonRecursive(*this, |
3778 test_kind, | 3786 test_kind, |
3779 type_arguments, | 3787 type_arguments, |
3780 other, | 3788 other, |
3781 other_type_arguments, | 3789 other_type_arguments, |
3782 bound_error, | 3790 bound_error, |
| 3791 bound_trail, |
3783 space); | 3792 space); |
3784 } | 3793 } |
3785 | 3794 |
3786 | 3795 |
3787 bool Class::IsTopLevel() const { | 3796 bool Class::IsTopLevel() const { |
3788 return Name() == Symbols::TopLevel().raw(); | 3797 return Name() == Symbols::TopLevel().raw(); |
3789 } | 3798 } |
3790 | 3799 |
3791 | 3800 |
3792 bool Class::IsPrivate() const { | 3801 bool Class::IsPrivate() const { |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4282 } | 4291 } |
4283 return true; | 4292 return true; |
4284 } | 4293 } |
4285 | 4294 |
4286 | 4295 |
4287 bool TypeArguments::TypeTest(TypeTestKind test_kind, | 4296 bool TypeArguments::TypeTest(TypeTestKind test_kind, |
4288 const TypeArguments& other, | 4297 const TypeArguments& other, |
4289 intptr_t from_index, | 4298 intptr_t from_index, |
4290 intptr_t len, | 4299 intptr_t len, |
4291 Error* bound_error, | 4300 Error* bound_error, |
| 4301 TrailPtr bound_trail, |
4292 Heap::Space space) const { | 4302 Heap::Space space) const { |
4293 ASSERT(Length() >= (from_index + len)); | 4303 ASSERT(Length() >= (from_index + len)); |
4294 ASSERT(!other.IsNull()); | 4304 ASSERT(!other.IsNull()); |
4295 ASSERT(other.Length() >= (from_index + len)); | 4305 ASSERT(other.Length() >= (from_index + len)); |
4296 AbstractType& type = AbstractType::Handle(); | 4306 AbstractType& type = AbstractType::Handle(); |
4297 AbstractType& other_type = AbstractType::Handle(); | 4307 AbstractType& other_type = AbstractType::Handle(); |
4298 for (intptr_t i = 0; i < len; i++) { | 4308 for (intptr_t i = 0; i < len; i++) { |
4299 type = TypeAt(from_index + i); | 4309 type = TypeAt(from_index + i); |
4300 ASSERT(!type.IsNull()); | 4310 ASSERT(!type.IsNull()); |
4301 other_type = other.TypeAt(from_index + i); | 4311 other_type = other.TypeAt(from_index + i); |
4302 ASSERT(!other_type.IsNull()); | 4312 ASSERT(!other_type.IsNull()); |
4303 if (!type.TypeTest(test_kind, other_type, bound_error, space)) { | 4313 if (!type.TypeTest(test_kind, |
| 4314 other_type, |
| 4315 bound_error, |
| 4316 bound_trail, |
| 4317 space)) { |
4304 return false; | 4318 return false; |
4305 } | 4319 } |
4306 } | 4320 } |
4307 return true; | 4321 return true; |
4308 } | 4322 } |
4309 | 4323 |
4310 | 4324 |
4311 bool TypeArguments::HasInstantiations() const { | 4325 bool TypeArguments::HasInstantiations() const { |
4312 const Array& prior_instantiations = Array::Handle(instantiations()); | 4326 const Array& prior_instantiations = Array::Handle(instantiations()); |
4313 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. | 4327 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. |
(...skipping 29 matching lines...) Expand all Loading... |
4343 } | 4357 } |
4344 | 4358 |
4345 | 4359 |
4346 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { | 4360 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { |
4347 return *TypeAddr(index); | 4361 return *TypeAddr(index); |
4348 } | 4362 } |
4349 | 4363 |
4350 | 4364 |
4351 void TypeArguments::SetTypeAt(intptr_t index, | 4365 void TypeArguments::SetTypeAt(intptr_t index, |
4352 const AbstractType& value) const { | 4366 const AbstractType& value) const { |
| 4367 ASSERT(!IsCanonical()); |
4353 StorePointer(TypeAddr(index), value.raw()); | 4368 StorePointer(TypeAddr(index), value.raw()); |
4354 } | 4369 } |
4355 | 4370 |
4356 | 4371 |
4357 bool TypeArguments::IsResolved() const { | 4372 bool TypeArguments::IsResolved() const { |
4358 AbstractType& type = AbstractType::Handle(); | 4373 AbstractType& type = AbstractType::Handle(); |
4359 const intptr_t num_types = Length(); | 4374 const intptr_t num_types = Length(); |
4360 for (intptr_t i = 0; i < num_types; i++) { | 4375 for (intptr_t i = 0; i < num_types; i++) { |
4361 type = TypeAt(i); | 4376 type = TypeAt(i); |
4362 if (!type.IsResolved()) { | 4377 if (!type.IsResolved()) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4520 return true; | 4535 return true; |
4521 } | 4536 } |
4522 } | 4537 } |
4523 return false; | 4538 return false; |
4524 } | 4539 } |
4525 | 4540 |
4526 | 4541 |
4527 RawTypeArguments* TypeArguments::InstantiateFrom( | 4542 RawTypeArguments* TypeArguments::InstantiateFrom( |
4528 const TypeArguments& instantiator_type_arguments, | 4543 const TypeArguments& instantiator_type_arguments, |
4529 Error* bound_error, | 4544 Error* bound_error, |
4530 TrailPtr trail, | 4545 TrailPtr instantiation_trail, |
| 4546 TrailPtr bound_trail, |
4531 Heap::Space space) const { | 4547 Heap::Space space) const { |
4532 ASSERT(!IsInstantiated()); | 4548 ASSERT(!IsInstantiated()); |
4533 if (!instantiator_type_arguments.IsNull() && | 4549 if (!instantiator_type_arguments.IsNull() && |
4534 IsUninstantiatedIdentity() && | 4550 IsUninstantiatedIdentity() && |
4535 (instantiator_type_arguments.Length() == Length())) { | 4551 (instantiator_type_arguments.Length() == Length())) { |
4536 return instantiator_type_arguments.raw(); | 4552 return instantiator_type_arguments.raw(); |
4537 } | 4553 } |
4538 const intptr_t num_types = Length(); | 4554 const intptr_t num_types = Length(); |
4539 TypeArguments& instantiated_array = | 4555 TypeArguments& instantiated_array = |
4540 TypeArguments::Handle(TypeArguments::New(num_types, space)); | 4556 TypeArguments::Handle(TypeArguments::New(num_types, space)); |
4541 AbstractType& type = AbstractType::Handle(); | 4557 AbstractType& type = AbstractType::Handle(); |
4542 for (intptr_t i = 0; i < num_types; i++) { | 4558 for (intptr_t i = 0; i < num_types; i++) { |
4543 type = TypeAt(i); | 4559 type = TypeAt(i); |
4544 // If this type argument T is null, the type A containing T in its flattened | 4560 // If this type argument T is null, the type A containing T in its flattened |
4545 // type argument vector V is recursive and is still being finalized. | 4561 // type argument vector V is recursive and is still being finalized. |
4546 // T is the type argument of a super type of A. T is being instantiated | 4562 // T is the type argument of a super type of A. T is being instantiated |
4547 // during finalization of V, which is also the instantiator. T depends | 4563 // during finalization of V, which is also the instantiator. T depends |
4548 // solely on the type parameters of A and will be replaced by a non-null | 4564 // solely on the type parameters of A and will be replaced by a non-null |
4549 // type before A is marked as finalized. | 4565 // type before A is marked as finalized. |
4550 if (!type.IsNull() && !type.IsInstantiated()) { | 4566 if (!type.IsNull() && !type.IsInstantiated()) { |
4551 type = type.InstantiateFrom(instantiator_type_arguments, | 4567 type = type.InstantiateFrom(instantiator_type_arguments, |
4552 bound_error, | 4568 bound_error, |
4553 trail, | 4569 instantiation_trail, |
| 4570 bound_trail, |
4554 space); | 4571 space); |
4555 } | 4572 } |
4556 instantiated_array.SetTypeAt(i, type); | 4573 instantiated_array.SetTypeAt(i, type); |
4557 } | 4574 } |
4558 return instantiated_array.raw(); | 4575 return instantiated_array.raw(); |
4559 } | 4576 } |
4560 | 4577 |
4561 | 4578 |
4562 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( | 4579 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( |
4563 const TypeArguments& instantiator_type_arguments, | 4580 const TypeArguments& instantiator_type_arguments, |
(...skipping 13 matching lines...) Expand all Loading... |
4577 return TypeArguments::RawCast(prior_instantiations.At(index + 1)); | 4594 return TypeArguments::RawCast(prior_instantiations.At(index + 1)); |
4578 } | 4595 } |
4579 if (prior_instantiations.At(index) == Smi::New(StubCode::kNoInstantiator)) { | 4596 if (prior_instantiations.At(index) == Smi::New(StubCode::kNoInstantiator)) { |
4580 break; | 4597 break; |
4581 } | 4598 } |
4582 index += 2; | 4599 index += 2; |
4583 } | 4600 } |
4584 // Cache lookup failed. Instantiate the type arguments. | 4601 // Cache lookup failed. Instantiate the type arguments. |
4585 TypeArguments& result = TypeArguments::Handle(); | 4602 TypeArguments& result = TypeArguments::Handle(); |
4586 result = InstantiateFrom( | 4603 result = InstantiateFrom( |
4587 instantiator_type_arguments, bound_error, NULL, Heap::kOld); | 4604 instantiator_type_arguments, bound_error, NULL, NULL, Heap::kOld); |
4588 if ((bound_error != NULL) && !bound_error->IsNull()) { | 4605 if ((bound_error != NULL) && !bound_error->IsNull()) { |
4589 return result.raw(); | 4606 return result.raw(); |
4590 } | 4607 } |
4591 // Instantiation did not result in bound error. Canonicalize type arguments. | 4608 // Instantiation did not result in bound error. Canonicalize type arguments. |
4592 result = result.Canonicalize(); | 4609 result = result.Canonicalize(); |
4593 // InstantiateAndCanonicalizeFrom is not reentrant. It cannot have been called | 4610 // InstantiateAndCanonicalizeFrom is not reentrant. It cannot have been called |
4594 // indirectly, so the prior_instantiations array cannot have grown. | 4611 // indirectly, so the prior_instantiations array cannot have grown. |
4595 ASSERT(prior_instantiations.raw() == instantiations()); | 4612 ASSERT(prior_instantiations.raw() == instantiations()); |
4596 // Add instantiator and result to instantiations array. | 4613 // Add instantiator and result to instantiations array. |
4597 intptr_t length = prior_instantiations.Length(); | 4614 intptr_t length = prior_instantiations.Length(); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4808 const intptr_t hash = Hash(); | 4825 const intptr_t hash = Hash(); |
4809 intptr_t index = FindIndexInCanonicalTypeArguments(zone, table, *this, hash); | 4826 intptr_t index = FindIndexInCanonicalTypeArguments(zone, table, *this, hash); |
4810 TypeArguments& result = TypeArguments::Handle(zone); | 4827 TypeArguments& result = TypeArguments::Handle(zone); |
4811 result ^= table.At(index); | 4828 result ^= table.At(index); |
4812 if (result.IsNull()) { | 4829 if (result.IsNull()) { |
4813 // Canonicalize each type argument. | 4830 // Canonicalize each type argument. |
4814 AbstractType& type_arg = AbstractType::Handle(zone); | 4831 AbstractType& type_arg = AbstractType::Handle(zone); |
4815 for (intptr_t i = 0; i < num_types; i++) { | 4832 for (intptr_t i = 0; i < num_types; i++) { |
4816 type_arg = TypeAt(i); | 4833 type_arg = TypeAt(i); |
4817 type_arg = type_arg.Canonicalize(trail); | 4834 type_arg = type_arg.Canonicalize(trail); |
| 4835 if (IsCanonical()) { |
| 4836 // Canonicalizing this type_arg canonicalized this type. |
| 4837 ASSERT(IsRecursive()); |
| 4838 return this->raw(); |
| 4839 } |
4818 SetTypeAt(i, type_arg); | 4840 SetTypeAt(i, type_arg); |
4819 } | 4841 } |
4820 // Canonicalization of a recursive type may change its hash. | 4842 // Canonicalization of a recursive type may change its hash. |
4821 intptr_t canonical_hash = hash; | 4843 intptr_t canonical_hash = hash; |
4822 if (IsRecursive()) { | 4844 if (IsRecursive()) { |
4823 canonical_hash = Hash(); | 4845 canonical_hash = Hash(); |
4824 } | 4846 } |
4825 // Canonicalization of the type argument's own type arguments may add an | 4847 // Canonicalization of the type argument's own type arguments may add an |
4826 // entry to the table, or even grow the table, and thereby change the | 4848 // entry to the table, or even grow the table, and thereby change the |
4827 // previously calculated index. | 4849 // previously calculated index. |
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5920 intptr_t parameter_position, | 5942 intptr_t parameter_position, |
5921 intptr_t other_parameter_position, | 5943 intptr_t other_parameter_position, |
5922 const TypeArguments& type_arguments, | 5944 const TypeArguments& type_arguments, |
5923 const Function& other, | 5945 const Function& other, |
5924 const TypeArguments& other_type_arguments, | 5946 const TypeArguments& other_type_arguments, |
5925 Error* bound_error, | 5947 Error* bound_error, |
5926 Heap::Space space) const { | 5948 Heap::Space space) const { |
5927 AbstractType& other_param_type = | 5949 AbstractType& other_param_type = |
5928 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); | 5950 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); |
5929 if (!other_param_type.IsInstantiated()) { | 5951 if (!other_param_type.IsInstantiated()) { |
5930 other_param_type = other_param_type.InstantiateFrom(other_type_arguments, | 5952 other_param_type = |
5931 bound_error, | 5953 other_param_type.InstantiateFrom(other_type_arguments, |
5932 NULL, // trail | 5954 bound_error, |
5933 space); | 5955 NULL, // instantiation_trail |
| 5956 NULL, // bound_trail |
| 5957 space); |
5934 ASSERT((bound_error == NULL) || bound_error->IsNull()); | 5958 ASSERT((bound_error == NULL) || bound_error->IsNull()); |
5935 } | 5959 } |
5936 if (other_param_type.IsDynamicType()) { | 5960 if (other_param_type.IsDynamicType()) { |
5937 return true; | 5961 return true; |
5938 } | 5962 } |
5939 AbstractType& param_type = | 5963 AbstractType& param_type = |
5940 AbstractType::Handle(ParameterTypeAt(parameter_position)); | 5964 AbstractType::Handle(ParameterTypeAt(parameter_position)); |
5941 if (!param_type.IsInstantiated()) { | 5965 if (!param_type.IsInstantiated()) { |
5942 param_type = param_type.InstantiateFrom( | 5966 param_type = param_type.InstantiateFrom(type_arguments, |
5943 type_arguments, bound_error, NULL /*trail*/, space); | 5967 bound_error, |
| 5968 NULL, // instantiation_trail |
| 5969 NULL, // bound_trail |
| 5970 space); |
5944 ASSERT((bound_error == NULL) || bound_error->IsNull()); | 5971 ASSERT((bound_error == NULL) || bound_error->IsNull()); |
5945 } | 5972 } |
5946 if (param_type.IsDynamicType()) { | 5973 if (param_type.IsDynamicType()) { |
5947 return test_kind == kIsSubtypeOf; | 5974 return test_kind == kIsSubtypeOf; |
5948 } | 5975 } |
5949 if (test_kind == kIsSubtypeOf) { | 5976 if (test_kind == kIsSubtypeOf) { |
5950 if (!param_type.IsSubtypeOf(other_param_type, bound_error, space) && | 5977 if (!param_type.IsSubtypeOf(other_param_type, bound_error, NULL, space) && |
5951 !other_param_type.IsSubtypeOf(param_type, bound_error, space)) { | 5978 !other_param_type.IsSubtypeOf(param_type, bound_error, NULL, space)) { |
5952 return false; | 5979 return false; |
5953 } | 5980 } |
5954 } else { | 5981 } else { |
5955 ASSERT(test_kind == kIsMoreSpecificThan); | 5982 ASSERT(test_kind == kIsMoreSpecificThan); |
5956 if (!param_type.IsMoreSpecificThan(other_param_type, bound_error, space)) { | 5983 if (!param_type.IsMoreSpecificThan( |
| 5984 other_param_type, bound_error, NULL, space)) { |
5957 return false; | 5985 return false; |
5958 } | 5986 } |
5959 } | 5987 } |
5960 return true; | 5988 return true; |
5961 } | 5989 } |
5962 | 5990 |
5963 | 5991 |
5964 bool Function::TypeTest(TypeTestKind test_kind, | 5992 bool Function::TypeTest(TypeTestKind test_kind, |
5965 const TypeArguments& type_arguments, | 5993 const TypeArguments& type_arguments, |
5966 const Function& other, | 5994 const Function& other, |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6369 ASSERT((num_fixed_params + num_opt_params) == num_params); | 6397 ASSERT((num_fixed_params + num_opt_params) == num_params); |
6370 intptr_t i = 0; | 6398 intptr_t i = 0; |
6371 if (name_visibility == kUserVisibleName) { | 6399 if (name_visibility == kUserVisibleName) { |
6372 // Hide implicit parameters. | 6400 // Hide implicit parameters. |
6373 i = NumImplicitParameters(); | 6401 i = NumImplicitParameters(); |
6374 } | 6402 } |
6375 String& name = String::Handle(zone); | 6403 String& name = String::Handle(zone); |
6376 while (i < num_fixed_params) { | 6404 while (i < num_fixed_params) { |
6377 param_type = ParameterTypeAt(i); | 6405 param_type = ParameterTypeAt(i); |
6378 ASSERT(!param_type.IsNull()); | 6406 ASSERT(!param_type.IsNull()); |
6379 if (instantiate && !param_type.IsInstantiated()) { | 6407 if (instantiate && |
| 6408 param_type.IsFinalized() && |
| 6409 !param_type.IsInstantiated()) { |
6380 param_type = param_type.InstantiateFrom(instantiator, NULL); | 6410 param_type = param_type.InstantiateFrom(instantiator, NULL); |
6381 } | 6411 } |
6382 name = param_type.BuildName(name_visibility); | 6412 name = param_type.BuildName(name_visibility); |
6383 pieces->Add(name); | 6413 pieces->Add(name); |
6384 if (i != (num_params - 1)) { | 6414 if (i != (num_params - 1)) { |
6385 pieces->Add(Symbols::CommaSpace()); | 6415 pieces->Add(Symbols::CommaSpace()); |
6386 } | 6416 } |
6387 i++; | 6417 i++; |
6388 } | 6418 } |
6389 if (num_opt_params > 0) { | 6419 if (num_opt_params > 0) { |
6390 if (num_opt_pos_params > 0) { | 6420 if (num_opt_pos_params > 0) { |
6391 pieces->Add(Symbols::LBracket()); | 6421 pieces->Add(Symbols::LBracket()); |
6392 } else { | 6422 } else { |
6393 pieces->Add(Symbols::LBrace()); | 6423 pieces->Add(Symbols::LBrace()); |
6394 } | 6424 } |
6395 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 6425 for (intptr_t i = num_fixed_params; i < num_params; i++) { |
6396 // The parameter name of an optional positional parameter does not need | 6426 // The parameter name of an optional positional parameter does not need |
6397 // to be part of the signature, since it is not used. | 6427 // to be part of the signature, since it is not used. |
6398 if (num_opt_named_params > 0) { | 6428 if (num_opt_named_params > 0) { |
6399 name = ParameterNameAt(i); | 6429 name = ParameterNameAt(i); |
6400 pieces->Add(name); | 6430 pieces->Add(name); |
6401 pieces->Add(Symbols::ColonSpace()); | 6431 pieces->Add(Symbols::ColonSpace()); |
6402 } | 6432 } |
6403 param_type = ParameterTypeAt(i); | 6433 param_type = ParameterTypeAt(i); |
6404 if (instantiate && !param_type.IsInstantiated()) { | 6434 if (instantiate && |
| 6435 param_type.IsFinalized() && |
| 6436 !param_type.IsInstantiated()) { |
6405 param_type = param_type.InstantiateFrom(instantiator, NULL); | 6437 param_type = param_type.InstantiateFrom(instantiator, NULL); |
6406 } | 6438 } |
6407 ASSERT(!param_type.IsNull()); | 6439 ASSERT(!param_type.IsNull()); |
6408 name = param_type.BuildName(name_visibility); | 6440 name = param_type.BuildName(name_visibility); |
6409 pieces->Add(name); | 6441 pieces->Add(name); |
6410 if (i != (num_params - 1)) { | 6442 if (i != (num_params - 1)) { |
6411 pieces->Add(Symbols::CommaSpace()); | 6443 pieces->Add(Symbols::CommaSpace()); |
6412 } | 6444 } |
6413 } | 6445 } |
6414 if (num_opt_pos_params > 0) { | 6446 if (num_opt_pos_params > 0) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6492 pieces.Add(Symbols::RAngleBracket()); | 6524 pieces.Add(Symbols::RAngleBracket()); |
6493 } | 6525 } |
6494 } | 6526 } |
6495 pieces.Add(Symbols::LParen()); | 6527 pieces.Add(Symbols::LParen()); |
6496 BuildSignatureParameters(instantiate, | 6528 BuildSignatureParameters(instantiate, |
6497 name_visibility, | 6529 name_visibility, |
6498 instantiator, | 6530 instantiator, |
6499 &pieces); | 6531 &pieces); |
6500 pieces.Add(Symbols::RParenArrow()); | 6532 pieces.Add(Symbols::RParenArrow()); |
6501 AbstractType& res_type = AbstractType::Handle(zone, result_type()); | 6533 AbstractType& res_type = AbstractType::Handle(zone, result_type()); |
6502 if (instantiate && !res_type.IsInstantiated()) { | 6534 if (instantiate && res_type.IsFinalized() && !res_type.IsInstantiated()) { |
6503 res_type = res_type.InstantiateFrom(instantiator, NULL); | 6535 res_type = res_type.InstantiateFrom(instantiator, NULL); |
6504 } | 6536 } |
6505 name = res_type.BuildName(name_visibility); | 6537 name = res_type.BuildName(name_visibility); |
6506 pieces.Add(name); | 6538 pieces.Add(name); |
6507 return Symbols::FromConcatAll(pieces); | 6539 return Symbols::FromConcatAll(pieces); |
6508 } | 6540 } |
6509 | 6541 |
6510 | 6542 |
6511 bool Function::HasInstantiatedSignature() const { | 6543 bool Function::HasInstantiatedSignature() const { |
6512 AbstractType& type = AbstractType::Handle(result_type()); | 6544 AbstractType& type = AbstractType::Handle(result_type()); |
(...skipping 7749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14262 Heap::kOld)) { | 14294 Heap::kOld)) { |
14263 return true; | 14295 return true; |
14264 } | 14296 } |
14265 } | 14297 } |
14266 } | 14298 } |
14267 if (!instantiated_other.IsType()) { | 14299 if (!instantiated_other.IsType()) { |
14268 return false; | 14300 return false; |
14269 } | 14301 } |
14270 other_class = instantiated_other.type_class(); | 14302 other_class = instantiated_other.type_class(); |
14271 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, | 14303 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |
14272 bound_error, Heap::kOld); | 14304 bound_error, NULL, Heap::kOld); |
14273 } | 14305 } |
14274 | 14306 |
14275 | 14307 |
14276 bool Instance::OperatorEquals(const Instance& other) const { | 14308 bool Instance::OperatorEquals(const Instance& other) const { |
14277 // TODO(koda): Optimize for all builtin classes and all classes | 14309 // TODO(koda): Optimize for all builtin classes and all classes |
14278 // that do not override operator==. | 14310 // that do not override operator==. |
14279 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); | 14311 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); |
14280 } | 14312 } |
14281 | 14313 |
14282 | 14314 |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14589 bool AbstractType::IsRecursive() const { | 14621 bool AbstractType::IsRecursive() const { |
14590 // AbstractType is an abstract class. | 14622 // AbstractType is an abstract class. |
14591 UNREACHABLE(); | 14623 UNREACHABLE(); |
14592 return false; | 14624 return false; |
14593 } | 14625 } |
14594 | 14626 |
14595 | 14627 |
14596 RawAbstractType* AbstractType::InstantiateFrom( | 14628 RawAbstractType* AbstractType::InstantiateFrom( |
14597 const TypeArguments& instantiator_type_arguments, | 14629 const TypeArguments& instantiator_type_arguments, |
14598 Error* bound_error, | 14630 Error* bound_error, |
14599 TrailPtr trail, | 14631 TrailPtr instantiation_trail, |
| 14632 TrailPtr bound_trail, |
14600 Heap::Space space) const { | 14633 Heap::Space space) const { |
14601 // AbstractType is an abstract class. | 14634 // AbstractType is an abstract class. |
14602 UNREACHABLE(); | 14635 UNREACHABLE(); |
14603 return NULL; | 14636 return NULL; |
14604 } | 14637 } |
14605 | 14638 |
14606 | 14639 |
14607 RawAbstractType* AbstractType::CloneUnfinalized() const { | 14640 RawAbstractType* AbstractType::CloneUnfinalized() const { |
14608 // AbstractType is an abstract class. | 14641 // AbstractType is an abstract class. |
14609 UNREACHABLE(); | 14642 UNREACHABLE(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14649 if (*trail == NULL) { | 14682 if (*trail == NULL) { |
14650 *trail = new Trail(Thread::Current()->zone(), 4); | 14683 *trail = new Trail(Thread::Current()->zone(), 4); |
14651 } else { | 14684 } else { |
14652 ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); | 14685 ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); |
14653 } | 14686 } |
14654 (*trail)->Add(*this); | 14687 (*trail)->Add(*this); |
14655 (*trail)->Add(buddy); | 14688 (*trail)->Add(buddy); |
14656 } | 14689 } |
14657 | 14690 |
14658 | 14691 |
| 14692 bool AbstractType::TestAndAddToTrail(TrailPtr* trail) const { |
| 14693 if (*trail == NULL) { |
| 14694 *trail = new Trail(Thread::Current()->zone(), 4); |
| 14695 } else { |
| 14696 const intptr_t len = (*trail)->length(); |
| 14697 for (intptr_t i = 0; i < len; i++) { |
| 14698 if ((*trail)->At(i).raw() == this->raw()) { |
| 14699 return true; |
| 14700 } |
| 14701 } |
| 14702 } |
| 14703 (*trail)->Add(*this); |
| 14704 return false; |
| 14705 } |
| 14706 |
| 14707 |
| 14708 bool AbstractType::TestAndAddBuddyToTrail(TrailPtr* trail, |
| 14709 const AbstractType& buddy) const { |
| 14710 if (*trail == NULL) { |
| 14711 *trail = new Trail(Thread::Current()->zone(), 4); |
| 14712 } else { |
| 14713 const intptr_t len = (*trail)->length(); |
| 14714 ASSERT((len % 2) == 0); |
| 14715 const bool this_is_typeref = IsTypeRef(); |
| 14716 const bool buddy_is_typeref = buddy.IsTypeRef(); |
| 14717 ASSERT(this_is_typeref || buddy_is_typeref); |
| 14718 for (intptr_t i = 0; i < len; i += 2) { |
| 14719 if ((((*trail)->At(i).raw() == this->raw()) || |
| 14720 (buddy_is_typeref && (*trail)->At(i).Equals(*this))) && |
| 14721 (((*trail)->At(i + 1).raw() == buddy.raw()) || |
| 14722 (this_is_typeref && (*trail)->At(i + 1).Equals(buddy)))) { |
| 14723 return true; |
| 14724 } |
| 14725 } |
| 14726 } |
| 14727 (*trail)->Add(*this); |
| 14728 (*trail)->Add(buddy); |
| 14729 return false; |
| 14730 } |
| 14731 |
| 14732 |
14659 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 14733 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
14660 Zone* zone = Thread::Current()->zone(); | 14734 Zone* zone = Thread::Current()->zone(); |
14661 if (IsBoundedType()) { | 14735 if (IsBoundedType()) { |
14662 const AbstractType& type = AbstractType::Handle( | 14736 const AbstractType& type = AbstractType::Handle( |
14663 BoundedType::Cast(*this).type()); | 14737 BoundedType::Cast(*this).type()); |
14664 if (name_visibility == kPrettyName) { | 14738 if (name_visibility == kPrettyName) { |
14665 return type.BuildName(kPrettyName); | 14739 return type.BuildName(kPrettyName); |
14666 } else if (name_visibility == kUserVisibleName) { | 14740 } else if (name_visibility == kUserVisibleName) { |
14667 return type.BuildName(kUserVisibleName); | 14741 return type.BuildName(kUserVisibleName); |
14668 } | 14742 } |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14855 | 14929 |
14856 bool AbstractType::IsDartFunctionType() const { | 14930 bool AbstractType::IsDartFunctionType() const { |
14857 return HasResolvedTypeClass() && | 14931 return HasResolvedTypeClass() && |
14858 (type_class() == Type::Handle(Type::Function()).type_class()); | 14932 (type_class() == Type::Handle(Type::Function()).type_class()); |
14859 } | 14933 } |
14860 | 14934 |
14861 | 14935 |
14862 bool AbstractType::TypeTest(TypeTestKind test_kind, | 14936 bool AbstractType::TypeTest(TypeTestKind test_kind, |
14863 const AbstractType& other, | 14937 const AbstractType& other, |
14864 Error* bound_error, | 14938 Error* bound_error, |
| 14939 TrailPtr bound_trail, |
14865 Heap::Space space) const { | 14940 Heap::Space space) const { |
14866 ASSERT(IsFinalized()); | 14941 ASSERT(IsFinalized()); |
14867 ASSERT(other.IsFinalized()); | 14942 ASSERT(other.IsFinalized()); |
14868 if (IsMalformed() || other.IsMalformed()) { | 14943 if (IsMalformed() || other.IsMalformed()) { |
14869 // Malformed types involved in subtype tests should be handled specially | 14944 // Malformed types involved in subtype tests should be handled specially |
14870 // by the caller. Malformed types should only be encountered here in a | 14945 // by the caller. Malformed types should only be encountered here in a |
14871 // more specific than test. | 14946 // more specific than test. |
14872 ASSERT(test_kind == kIsMoreSpecificThan); | 14947 ASSERT(test_kind == kIsMoreSpecificThan); |
14873 return false; | 14948 return false; |
14874 } | 14949 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14925 if (type_param.Equals(other_type_param)) { | 15000 if (type_param.Equals(other_type_param)) { |
14926 return true; | 15001 return true; |
14927 } | 15002 } |
14928 } | 15003 } |
14929 const AbstractType& bound = AbstractType::Handle(zone, type_param.bound()); | 15004 const AbstractType& bound = AbstractType::Handle(zone, type_param.bound()); |
14930 // We may be checking bounds at finalization time and can encounter | 15005 // We may be checking bounds at finalization time and can encounter |
14931 // a still unfinalized bound. Finalizing the bound here may lead to cycles. | 15006 // a still unfinalized bound. Finalizing the bound here may lead to cycles. |
14932 if (!bound.IsFinalized()) { | 15007 if (!bound.IsFinalized()) { |
14933 return false; // TODO(regis): Return "maybe after instantiation". | 15008 return false; // TODO(regis): Return "maybe after instantiation". |
14934 } | 15009 } |
14935 if (bound.IsMoreSpecificThan(other, bound_error)) { | 15010 // The current bound_trail cannot be used, because operands are swapped and |
| 15011 // the test is different anyway (more specific vs. subtype). |
| 15012 if (bound.IsMoreSpecificThan(other, bound_error, NULL)) { |
14936 return true; | 15013 return true; |
14937 } | 15014 } |
14938 return false; // TODO(regis): We should return "maybe after instantiation". | 15015 return false; // TODO(regis): We should return "maybe after instantiation". |
14939 } | 15016 } |
14940 if (other.IsTypeParameter()) { | 15017 if (other.IsTypeParameter()) { |
14941 return false; // TODO(regis): We should return "maybe after instantiation". | 15018 return false; // TODO(regis): We should return "maybe after instantiation". |
14942 } | 15019 } |
14943 const Class& type_cls = Class::Handle(zone, type_class()); | 15020 const Class& type_cls = Class::Handle(zone, type_class()); |
14944 // Function types cannot be handled by Class::TypeTest(). | 15021 // Function types cannot be handled by Class::TypeTest(). |
14945 const bool other_is_dart_function_type = other.IsDartFunctionType(); | 15022 const bool other_is_dart_function_type = other.IsDartFunctionType(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14985 } | 15062 } |
14986 } | 15063 } |
14987 if (IsFunctionType()) { | 15064 if (IsFunctionType()) { |
14988 return false; | 15065 return false; |
14989 } | 15066 } |
14990 return type_cls.TypeTest(test_kind, | 15067 return type_cls.TypeTest(test_kind, |
14991 TypeArguments::Handle(zone, arguments()), | 15068 TypeArguments::Handle(zone, arguments()), |
14992 Class::Handle(zone, other.type_class()), | 15069 Class::Handle(zone, other.type_class()), |
14993 TypeArguments::Handle(zone, other.arguments()), | 15070 TypeArguments::Handle(zone, other.arguments()), |
14994 bound_error, | 15071 bound_error, |
| 15072 bound_trail, |
14995 space); | 15073 space); |
14996 } | 15074 } |
14997 | 15075 |
14998 | 15076 |
14999 intptr_t AbstractType::Hash() const { | 15077 intptr_t AbstractType::Hash() const { |
15000 // AbstractType is an abstract class. | 15078 // AbstractType is an abstract class. |
15001 UNREACHABLE(); | 15079 UNREACHABLE(); |
15002 return 0; | 15080 return 0; |
15003 } | 15081 } |
15004 | 15082 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15229 num_type_args = len; | 15307 num_type_args = len; |
15230 len = cls.NumTypeParameters(); // Check the type parameters only. | 15308 len = cls.NumTypeParameters(); // Check the type parameters only. |
15231 } | 15309 } |
15232 return (len == 0) || args.IsSubvectorInstantiated(num_type_args - len, len); | 15310 return (len == 0) || args.IsSubvectorInstantiated(num_type_args - len, len); |
15233 } | 15311 } |
15234 | 15312 |
15235 | 15313 |
15236 RawAbstractType* Type::InstantiateFrom( | 15314 RawAbstractType* Type::InstantiateFrom( |
15237 const TypeArguments& instantiator_type_arguments, | 15315 const TypeArguments& instantiator_type_arguments, |
15238 Error* bound_error, | 15316 Error* bound_error, |
15239 TrailPtr trail, | 15317 TrailPtr instantiation_trail, |
| 15318 TrailPtr bound_trail, |
15240 Heap::Space space) const { | 15319 Heap::Space space) const { |
15241 Zone* zone = Thread::Current()->zone(); | 15320 Zone* zone = Thread::Current()->zone(); |
15242 ASSERT(IsFinalized() || IsBeingFinalized()); | 15321 ASSERT(IsFinalized() || IsBeingFinalized()); |
15243 ASSERT(!IsInstantiated()); | 15322 ASSERT(!IsInstantiated()); |
15244 // Return the uninstantiated type unchanged if malformed. No copy needed. | 15323 // Return the uninstantiated type unchanged if malformed. No copy needed. |
15245 if (IsMalformed()) { | 15324 if (IsMalformed()) { |
15246 return raw(); | 15325 return raw(); |
15247 } | 15326 } |
15248 // Instantiating this type with its own type arguments as instantiator can | 15327 // Instantiating this type with its own type arguments as instantiator can |
15249 // occur during finalization and bounds checking. Return the type unchanged. | 15328 // occur during finalization and bounds checking. Return the type unchanged. |
15250 if (arguments() == instantiator_type_arguments.raw()) { | 15329 if (arguments() == instantiator_type_arguments.raw()) { |
15251 return raw(); | 15330 return raw(); |
15252 } | 15331 } |
15253 // If this type is recursive, we may already be instantiating it. | |
15254 Type& instantiated_type = Type::Handle(zone); | |
15255 instantiated_type ^= OnlyBuddyInTrail(trail); | |
15256 if (!instantiated_type.IsNull()) { | |
15257 ASSERT(IsRecursive()); | |
15258 return instantiated_type.raw(); | |
15259 } | |
15260 // Note that the type class has to be resolved at this time, but not | 15332 // Note that the type class has to be resolved at this time, but not |
15261 // necessarily finalized yet. We may be checking bounds at compile time or | 15333 // necessarily finalized yet. We may be checking bounds at compile time or |
15262 // finalizing the type argument vector of a recursive type. | 15334 // finalizing the type argument vector of a recursive type. |
15263 const Class& cls = Class::Handle(zone, type_class()); | 15335 const Class& cls = Class::Handle(zone, type_class()); |
15264 | 15336 TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments()); |
| 15337 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); |
| 15338 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
| 15339 bound_error, |
| 15340 instantiation_trail, |
| 15341 bound_trail, |
| 15342 space); |
15265 // This uninstantiated type is not modified, as it can be instantiated | 15343 // This uninstantiated type is not modified, as it can be instantiated |
15266 // with different instantiators. Allocate a new instantiated version of it. | 15344 // with different instantiators. Allocate a new instantiated version of it. |
15267 instantiated_type = | 15345 const Type& instantiated_type = |
15268 Type::New(cls, TypeArguments::Handle(zone), token_pos(), space); | 15346 Type::Handle(zone, Type::New(cls, type_arguments, token_pos(), space)); |
15269 TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments()); | |
15270 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); | |
15271 if (type_arguments.IsRecursive()) { | |
15272 AddOnlyBuddyToTrail(&trail, instantiated_type); | |
15273 } | |
15274 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | |
15275 bound_error, | |
15276 trail, | |
15277 space); | |
15278 instantiated_type.set_arguments(type_arguments); | |
15279 if (IsFinalized()) { | 15347 if (IsFinalized()) { |
15280 instantiated_type.SetIsFinalized(); | 15348 instantiated_type.SetIsFinalized(); |
15281 } else { | 15349 } else { |
15282 instantiated_type.SetIsResolved(); | 15350 instantiated_type.SetIsResolved(); |
15283 } | 15351 } |
15284 // Canonicalization is not part of instantiation. | 15352 // Canonicalization is not part of instantiation. |
15285 return instantiated_type.raw(); | 15353 return instantiated_type.raw(); |
15286 } | 15354 } |
15287 | 15355 |
15288 | 15356 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15432 return Object::dynamic_type().raw(); | 15500 return Object::dynamic_type().raw(); |
15433 } | 15501 } |
15434 // Fast canonical lookup/registry for simple types. | 15502 // Fast canonical lookup/registry for simple types. |
15435 if (!cls.IsGeneric() && !cls.IsClosureClass()) { | 15503 if (!cls.IsGeneric() && !cls.IsClosureClass()) { |
15436 type = cls.CanonicalType(); | 15504 type = cls.CanonicalType(); |
15437 if (type.IsNull()) { | 15505 if (type.IsNull()) { |
15438 ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate())); | 15506 ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate())); |
15439 // Canonicalize the type arguments of the supertype, if any. | 15507 // Canonicalize the type arguments of the supertype, if any. |
15440 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 15508 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
15441 type_args = type_args.Canonicalize(trail); | 15509 type_args = type_args.Canonicalize(trail); |
| 15510 if (IsCanonical()) { |
| 15511 // Canonicalizing type_args canonicalized this type. |
| 15512 ASSERT(IsRecursive()); |
| 15513 return this->raw(); |
| 15514 } |
15442 set_arguments(type_args); | 15515 set_arguments(type_args); |
15443 type = cls.CanonicalType(); // May be set while canonicalizing type args. | 15516 type = cls.CanonicalType(); // May be set while canonicalizing type args. |
15444 if (type.IsNull()) { | 15517 if (type.IsNull()) { |
15445 cls.set_canonical_types(*this); | 15518 cls.set_canonical_types(*this); |
15446 SetCanonical(); | 15519 SetCanonical(); |
15447 return this->raw(); | 15520 return this->raw(); |
15448 } | 15521 } |
15449 } | 15522 } |
15450 ASSERT(this->Equals(type)); | 15523 ASSERT(this->Equals(type)); |
15451 ASSERT(type.IsCanonical()); | 15524 ASSERT(type.IsCanonical()); |
(...skipping 24 matching lines...) Expand all Loading... |
15476 index++; | 15549 index++; |
15477 } | 15550 } |
15478 // The type was not found in the table. It is not canonical yet. | 15551 // The type was not found in the table. It is not canonical yet. |
15479 | 15552 |
15480 // Canonicalize the type arguments. | 15553 // Canonicalize the type arguments. |
15481 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 15554 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
15482 // In case the type is first canonicalized at runtime, its type argument | 15555 // In case the type is first canonicalized at runtime, its type argument |
15483 // vector may be longer than necessary. This is not an issue. | 15556 // vector may be longer than necessary. This is not an issue. |
15484 ASSERT(type_args.IsNull() || (type_args.Length() >= cls.NumTypeArguments())); | 15557 ASSERT(type_args.IsNull() || (type_args.Length() >= cls.NumTypeArguments())); |
15485 type_args = type_args.Canonicalize(trail); | 15558 type_args = type_args.Canonicalize(trail); |
| 15559 if (IsCanonical()) { |
| 15560 // Canonicalizing type_args canonicalized this type as a side effect. |
| 15561 ASSERT(IsRecursive()); |
| 15562 return this->raw(); |
| 15563 } |
15486 set_arguments(type_args); | 15564 set_arguments(type_args); |
15487 | 15565 |
15488 // Canonicalizing the type arguments may have changed the index, may have | 15566 // Canonicalizing the type arguments may have changed the index, may have |
15489 // grown the table, or may even have canonicalized this type. | 15567 // grown the table, or may even have canonicalized this type. |
15490 canonical_types ^= cls.canonical_types(); | 15568 canonical_types ^= cls.canonical_types(); |
15491 if (canonical_types.IsNull()) { | 15569 if (canonical_types.IsNull()) { |
15492 canonical_types = empty_array().raw(); | 15570 canonical_types = empty_array().raw(); |
15493 } | 15571 } |
15494 length = canonical_types.Length(); | 15572 length = canonical_types.Length(); |
15495 while (index < length) { | 15573 while (index < length) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15534 } | 15612 } |
15535 | 15613 |
15536 | 15614 |
15537 void Type::set_type_class(const Object& value) const { | 15615 void Type::set_type_class(const Object& value) const { |
15538 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); | 15616 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); |
15539 StorePointer(&raw_ptr()->type_class_, value.raw()); | 15617 StorePointer(&raw_ptr()->type_class_, value.raw()); |
15540 } | 15618 } |
15541 | 15619 |
15542 | 15620 |
15543 void Type::set_arguments(const TypeArguments& value) const { | 15621 void Type::set_arguments(const TypeArguments& value) const { |
| 15622 ASSERT(!IsCanonical()); |
15544 StorePointer(&raw_ptr()->arguments_, value.raw()); | 15623 StorePointer(&raw_ptr()->arguments_, value.raw()); |
15545 } | 15624 } |
15546 | 15625 |
15547 | 15626 |
15548 RawType* Type::New(Heap::Space space) { | 15627 RawType* Type::New(Heap::Space space) { |
15549 RawObject* raw = Object::Allocate(Type::kClassId, | 15628 RawObject* raw = Object::Allocate(Type::kClassId, |
15550 Type::InstanceSize(), | 15629 Type::InstanceSize(), |
15551 space); | 15630 space); |
15552 return reinterpret_cast<RawType*>(raw); | 15631 return reinterpret_cast<RawType*>(raw); |
15553 } | 15632 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15698 return | 15777 return |
15699 (num_type_params == 0) || | 15778 (num_type_params == 0) || |
15700 type_arguments.IsSubvectorInstantiated(num_type_args - num_type_params, | 15779 type_arguments.IsSubvectorInstantiated(num_type_args - num_type_params, |
15701 num_type_params); | 15780 num_type_params); |
15702 } | 15781 } |
15703 | 15782 |
15704 | 15783 |
15705 RawAbstractType* FunctionType::InstantiateFrom( | 15784 RawAbstractType* FunctionType::InstantiateFrom( |
15706 const TypeArguments& instantiator_type_arguments, | 15785 const TypeArguments& instantiator_type_arguments, |
15707 Error* bound_error, | 15786 Error* bound_error, |
15708 TrailPtr trail, | 15787 TrailPtr instantiation_trail, |
| 15788 TrailPtr bound_trail, |
15709 Heap::Space space) const { | 15789 Heap::Space space) const { |
15710 Zone* zone = Thread::Current()->zone(); | 15790 Zone* zone = Thread::Current()->zone(); |
15711 ASSERT(IsFinalized() || IsBeingFinalized()); | 15791 ASSERT(IsFinalized() || IsBeingFinalized()); |
15712 ASSERT(!IsInstantiated()); | 15792 ASSERT(!IsInstantiated()); |
15713 ASSERT(!IsMalformed()); // FunctionType cannot be malformed. | 15793 ASSERT(!IsMalformed()); // FunctionType cannot be malformed. |
15714 // Instantiating this type with its own type arguments as instantiator can | 15794 // Instantiating this type with its own type arguments as instantiator can |
15715 // occur during finalization and bounds checking. Return the type unchanged. | 15795 // occur during finalization and bounds checking. Return the type unchanged. |
15716 if (arguments() == instantiator_type_arguments.raw()) { | 15796 if (arguments() == instantiator_type_arguments.raw()) { |
15717 return raw(); | 15797 return raw(); |
15718 } | 15798 } |
15719 // If this type is recursive, we may already be instantiating it. | |
15720 FunctionType& instantiated_type = FunctionType::Handle(zone); | |
15721 instantiated_type ^= OnlyBuddyInTrail(trail); | |
15722 if (!instantiated_type.IsNull()) { | |
15723 ASSERT(IsRecursive()); | |
15724 return instantiated_type.raw(); | |
15725 } | |
15726 // Note that the scope class has to be resolved at this time, but not | 15799 // Note that the scope class has to be resolved at this time, but not |
15727 // necessarily finalized yet. We may be checking bounds at compile time or | 15800 // necessarily finalized yet. We may be checking bounds at compile time or |
15728 // finalizing the type argument vector of a recursive type. | 15801 // finalizing the type argument vector of a recursive type. |
15729 const Class& cls = Class::Handle(zone, scope_class()); | 15802 const Class& cls = Class::Handle(zone, scope_class()); |
15730 | 15803 TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments()); |
| 15804 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); |
| 15805 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
| 15806 bound_error, |
| 15807 instantiation_trail, |
| 15808 bound_trail, |
| 15809 space); |
15731 // This uninstantiated type is not modified, as it can be instantiated | 15810 // This uninstantiated type is not modified, as it can be instantiated |
15732 // with different instantiators. Allocate a new instantiated version of it. | 15811 // with different instantiators. Allocate a new instantiated version of it. |
15733 instantiated_type = | 15812 const FunctionType& instantiated_type = FunctionType::Handle(zone, |
15734 FunctionType::New(cls, | 15813 FunctionType::New(cls, |
15735 TypeArguments::Handle(zone), | 15814 type_arguments, |
15736 Function::Handle(zone, signature()), | 15815 Function::Handle(zone, signature()), |
15737 token_pos(), | 15816 token_pos(), |
15738 space); | 15817 space)); |
15739 TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments()); | |
15740 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); | |
15741 if (type_arguments.IsRecursive()) { | |
15742 AddOnlyBuddyToTrail(&trail, instantiated_type); | |
15743 } | |
15744 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | |
15745 bound_error, | |
15746 trail, | |
15747 space); | |
15748 instantiated_type.set_arguments(type_arguments); | |
15749 if (IsFinalized()) { | 15818 if (IsFinalized()) { |
15750 instantiated_type.SetIsFinalized(); | 15819 instantiated_type.SetIsFinalized(); |
15751 } else { | 15820 } else { |
15752 instantiated_type.SetIsResolved(); | 15821 instantiated_type.SetIsResolved(); |
15753 } | 15822 } |
15754 // Canonicalization is not part of instantiation. | 15823 // Canonicalization is not part of instantiation. |
15755 return instantiated_type.raw(); | 15824 return instantiated_type.raw(); |
15756 } | 15825 } |
15757 | 15826 |
15758 | 15827 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15946 } | 16015 } |
15947 // The type was not found in the table. It is not canonical yet. | 16016 // The type was not found in the table. It is not canonical yet. |
15948 | 16017 |
15949 // Canonicalize the type arguments. | 16018 // Canonicalize the type arguments. |
15950 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 16019 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
15951 // In case the type is first canonicalized at runtime, its type argument | 16020 // In case the type is first canonicalized at runtime, its type argument |
15952 // vector may be longer than necessary. This is not an issue. | 16021 // vector may be longer than necessary. This is not an issue. |
15953 ASSERT(type_args.IsNull() || | 16022 ASSERT(type_args.IsNull() || |
15954 (type_args.Length() >= scope_cls.NumTypeArguments())); | 16023 (type_args.Length() >= scope_cls.NumTypeArguments())); |
15955 type_args = type_args.Canonicalize(trail); | 16024 type_args = type_args.Canonicalize(trail); |
| 16025 if (IsCanonical()) { |
| 16026 // Canonicalizing type_args canonicalized this type as a side effect. |
| 16027 ASSERT(IsRecursive()); |
| 16028 // Cycles via typedefs are detected and disallowed, but a function type can |
| 16029 // be recursive due to a cycle in its type arguments. |
| 16030 return this->raw(); |
| 16031 } |
15956 set_arguments(type_args); | 16032 set_arguments(type_args); |
15957 | 16033 |
15958 // Replace the actual function by a signature function. | 16034 // Replace the actual function by a signature function. |
15959 const Function& fun = Function::Handle(zone, signature()); | 16035 const Function& fun = Function::Handle(zone, signature()); |
15960 if (!fun.IsSignatureFunction()) { | 16036 if (!fun.IsSignatureFunction()) { |
15961 Function& sig_fun = Function::Handle(zone, | 16037 Function& sig_fun = Function::Handle(zone, |
15962 Function::NewSignatureFunction(scope_cls, TokenPosition::kNoSource)); | 16038 Function::NewSignatureFunction(scope_cls, TokenPosition::kNoSource)); |
15963 type = fun.result_type(); | 16039 type = fun.result_type(); |
15964 type = type.Canonicalize(trail); | 16040 type = type.Canonicalize(trail); |
15965 sig_fun.set_result_type(type); | 16041 sig_fun.set_result_type(type); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16043 } | 16119 } |
16044 | 16120 |
16045 | 16121 |
16046 void FunctionType::set_scope_class(const Class& value) const { | 16122 void FunctionType::set_scope_class(const Class& value) const { |
16047 ASSERT(!value.IsNull()); | 16123 ASSERT(!value.IsNull()); |
16048 StorePointer(&raw_ptr()->scope_class_, value.raw()); | 16124 StorePointer(&raw_ptr()->scope_class_, value.raw()); |
16049 } | 16125 } |
16050 | 16126 |
16051 | 16127 |
16052 void FunctionType::set_arguments(const TypeArguments& value) const { | 16128 void FunctionType::set_arguments(const TypeArguments& value) const { |
| 16129 ASSERT(!IsCanonical()); |
16053 StorePointer(&raw_ptr()->arguments_, value.raw()); | 16130 StorePointer(&raw_ptr()->arguments_, value.raw()); |
16054 } | 16131 } |
16055 | 16132 |
16056 | 16133 |
16057 void FunctionType::set_signature(const Function& value) const { | 16134 void FunctionType::set_signature(const Function& value) const { |
16058 StorePointer(&raw_ptr()->signature_, value.raw()); | 16135 StorePointer(&raw_ptr()->signature_, value.raw()); |
16059 } | 16136 } |
16060 | 16137 |
16061 | 16138 |
16062 RawFunctionType* FunctionType::New(Heap::Space space) { | 16139 RawFunctionType* FunctionType::New(Heap::Space space) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16143 if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { | 16220 if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { |
16144 return true; | 16221 return true; |
16145 } | 16222 } |
16146 return AbstractType::Handle(type()).IsEquivalent(other, trail); | 16223 return AbstractType::Handle(type()).IsEquivalent(other, trail); |
16147 } | 16224 } |
16148 | 16225 |
16149 | 16226 |
16150 RawTypeRef* TypeRef::InstantiateFrom( | 16227 RawTypeRef* TypeRef::InstantiateFrom( |
16151 const TypeArguments& instantiator_type_arguments, | 16228 const TypeArguments& instantiator_type_arguments, |
16152 Error* bound_error, | 16229 Error* bound_error, |
16153 TrailPtr trail, | 16230 TrailPtr instantiation_trail, |
| 16231 TrailPtr bound_trail, |
16154 Heap::Space space) const { | 16232 Heap::Space space) const { |
16155 TypeRef& instantiated_type_ref = TypeRef::Handle(); | 16233 TypeRef& instantiated_type_ref = TypeRef::Handle(); |
16156 instantiated_type_ref ^= OnlyBuddyInTrail(trail); | 16234 instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail); |
16157 if (!instantiated_type_ref.IsNull()) { | 16235 if (!instantiated_type_ref.IsNull()) { |
16158 return instantiated_type_ref.raw(); | 16236 return instantiated_type_ref.raw(); |
16159 } | 16237 } |
| 16238 instantiated_type_ref = TypeRef::New(); |
| 16239 AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref); |
| 16240 |
16160 AbstractType& ref_type = AbstractType::Handle(type()); | 16241 AbstractType& ref_type = AbstractType::Handle(type()); |
16161 ASSERT(!ref_type.IsTypeRef()); | 16242 ASSERT(!ref_type.IsTypeRef()); |
16162 AbstractType& instantiated_ref_type = AbstractType::Handle(); | 16243 AbstractType& instantiated_ref_type = AbstractType::Handle(); |
16163 instantiated_ref_type = ref_type.InstantiateFrom( | 16244 instantiated_ref_type = ref_type.InstantiateFrom( |
16164 instantiator_type_arguments, bound_error, trail, space); | 16245 instantiator_type_arguments, |
| 16246 bound_error, |
| 16247 instantiation_trail, |
| 16248 bound_trail, |
| 16249 space); |
16165 ASSERT(!instantiated_ref_type.IsTypeRef()); | 16250 ASSERT(!instantiated_ref_type.IsTypeRef()); |
16166 instantiated_type_ref = TypeRef::New(instantiated_ref_type); | 16251 instantiated_type_ref.set_type(instantiated_ref_type); |
16167 AddOnlyBuddyToTrail(&trail, instantiated_type_ref); | |
16168 return instantiated_type_ref.raw(); | 16252 return instantiated_type_ref.raw(); |
16169 } | 16253 } |
16170 | 16254 |
16171 | 16255 |
16172 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, | 16256 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, |
16173 TrailPtr trail) const { | 16257 TrailPtr trail) const { |
16174 TypeRef& cloned_type_ref = TypeRef::Handle(); | 16258 TypeRef& cloned_type_ref = TypeRef::Handle(); |
16175 cloned_type_ref ^= OnlyBuddyInTrail(trail); | 16259 cloned_type_ref ^= OnlyBuddyInTrail(trail); |
16176 if (!cloned_type_ref.IsNull()) { | 16260 if (!cloned_type_ref.IsNull()) { |
16177 return cloned_type_ref.raw(); | 16261 return cloned_type_ref.raw(); |
16178 } | 16262 } |
| 16263 cloned_type_ref = TypeRef::New(); |
| 16264 AddOnlyBuddyToTrail(&trail, cloned_type_ref); |
16179 AbstractType& ref_type = AbstractType::Handle(type()); | 16265 AbstractType& ref_type = AbstractType::Handle(type()); |
16180 ASSERT(!ref_type.IsTypeRef()); | 16266 ASSERT(!ref_type.IsTypeRef()); |
16181 AbstractType& cloned_ref_type = AbstractType::Handle(); | 16267 AbstractType& cloned_ref_type = AbstractType::Handle(); |
16182 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); | 16268 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); |
16183 ASSERT(!cloned_ref_type.IsTypeRef()); | 16269 ASSERT(!cloned_ref_type.IsTypeRef()); |
16184 cloned_type_ref = TypeRef::New(cloned_ref_type); | 16270 cloned_type_ref.set_type(cloned_ref_type); |
16185 AddOnlyBuddyToTrail(&trail, cloned_type_ref); | |
16186 return cloned_type_ref.raw(); | 16271 return cloned_type_ref.raw(); |
16187 } | 16272 } |
16188 | 16273 |
16189 | 16274 |
16190 void TypeRef::set_type(const AbstractType& value) const { | 16275 void TypeRef::set_type(const AbstractType& value) const { |
16191 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); | 16276 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); |
16192 ASSERT(!value.IsTypeRef()); | 16277 ASSERT(!value.IsTypeRef()); |
16193 StorePointer(&raw_ptr()->type_, value.raw()); | 16278 StorePointer(&raw_ptr()->type_, value.raw()); |
16194 } | 16279 } |
16195 | 16280 |
(...skipping 16 matching lines...) Expand all Loading... |
16212 | 16297 |
16213 | 16298 |
16214 intptr_t TypeRef::Hash() const { | 16299 intptr_t TypeRef::Hash() const { |
16215 // Do not calculate the hash of the referenced type to avoid divergence. | 16300 // Do not calculate the hash of the referenced type to avoid divergence. |
16216 const uint32_t result = | 16301 const uint32_t result = |
16217 Class::Handle(AbstractType::Handle(type()).type_class()).id(); | 16302 Class::Handle(AbstractType::Handle(type()).type_class()).id(); |
16218 return FinalizeHash(result); | 16303 return FinalizeHash(result); |
16219 } | 16304 } |
16220 | 16305 |
16221 | 16306 |
16222 bool TypeRef::TestAndAddToTrail(TrailPtr* trail) const { | |
16223 if (*trail == NULL) { | |
16224 *trail = new Trail(Thread::Current()->zone(), 4); | |
16225 } else { | |
16226 const intptr_t len = (*trail)->length(); | |
16227 for (intptr_t i = 0; i < len; i++) { | |
16228 if ((*trail)->At(i).raw() == this->raw()) { | |
16229 return true; | |
16230 } | |
16231 } | |
16232 } | |
16233 (*trail)->Add(*this); | |
16234 return false; | |
16235 } | |
16236 | |
16237 | |
16238 bool TypeRef::TestAndAddBuddyToTrail(TrailPtr* trail, | |
16239 const AbstractType& buddy) const { | |
16240 if (*trail == NULL) { | |
16241 *trail = new Trail(Thread::Current()->zone(), 4); | |
16242 } else { | |
16243 const intptr_t len = (*trail)->length(); | |
16244 ASSERT((len % 2) == 0); | |
16245 for (intptr_t i = 0; i < len; i += 2) { | |
16246 if (((*trail)->At(i).raw() == this->raw()) && | |
16247 ((*trail)->At(i + 1).raw() == buddy.raw())) { | |
16248 return true; | |
16249 } | |
16250 } | |
16251 } | |
16252 (*trail)->Add(*this); | |
16253 (*trail)->Add(buddy); | |
16254 return false; | |
16255 } | |
16256 | |
16257 | |
16258 RawTypeRef* TypeRef::New() { | 16307 RawTypeRef* TypeRef::New() { |
16259 RawObject* raw = Object::Allocate(TypeRef::kClassId, | 16308 RawObject* raw = Object::Allocate(TypeRef::kClassId, |
16260 TypeRef::InstanceSize(), | 16309 TypeRef::InstanceSize(), |
16261 Heap::kOld); | 16310 Heap::kOld); |
16262 return reinterpret_cast<RawTypeRef*>(raw); | 16311 return reinterpret_cast<RawTypeRef*>(raw); |
16263 } | 16312 } |
16264 | 16313 |
16265 | 16314 |
16266 RawTypeRef* TypeRef::New(const AbstractType& type) { | 16315 RawTypeRef* TypeRef::New(const AbstractType& type) { |
16267 const TypeRef& result = TypeRef::Handle(TypeRef::New()); | 16316 const TypeRef& result = TypeRef::Handle(TypeRef::New()); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16336 | 16385 |
16337 | 16386 |
16338 void TypeParameter::set_bound(const AbstractType& value) const { | 16387 void TypeParameter::set_bound(const AbstractType& value) const { |
16339 StorePointer(&raw_ptr()->bound_, value.raw()); | 16388 StorePointer(&raw_ptr()->bound_, value.raw()); |
16340 } | 16389 } |
16341 | 16390 |
16342 | 16391 |
16343 RawAbstractType* TypeParameter::InstantiateFrom( | 16392 RawAbstractType* TypeParameter::InstantiateFrom( |
16344 const TypeArguments& instantiator_type_arguments, | 16393 const TypeArguments& instantiator_type_arguments, |
16345 Error* bound_error, | 16394 Error* bound_error, |
16346 TrailPtr trail, | 16395 TrailPtr instantiation_trail, |
| 16396 TrailPtr bound_trail, |
16347 Heap::Space space) const { | 16397 Heap::Space space) const { |
16348 ASSERT(IsFinalized()); | 16398 ASSERT(IsFinalized()); |
16349 if (instantiator_type_arguments.IsNull()) { | 16399 if (instantiator_type_arguments.IsNull()) { |
16350 return Type::DynamicType(); | 16400 return Type::DynamicType(); |
16351 } | 16401 } |
16352 const AbstractType& type_arg = AbstractType::Handle( | 16402 const AbstractType& type_arg = AbstractType::Handle( |
16353 instantiator_type_arguments.TypeAt(index())); | 16403 instantiator_type_arguments.TypeAt(index())); |
16354 // There is no need to canonicalize the instantiated type parameter, since all | 16404 // There is no need to canonicalize the instantiated type parameter, since all |
16355 // type arguments are canonicalized at type finalization time. It would be too | 16405 // type arguments are canonicalized at type finalization time. It would be too |
16356 // early to canonicalize the returned type argument here, since instantiation | 16406 // early to canonicalize the returned type argument here, since instantiation |
16357 // not only happens at run time, but also during type finalization. | 16407 // not only happens at run time, but also during type finalization. |
| 16408 |
| 16409 // If the instantiated type parameter type_arg is a BoundedType, it means that |
| 16410 // it is still uninstantiated and that we are instantiating at finalization |
| 16411 // time (i.e. compile time). |
| 16412 // Indeed, the instantiator (type arguments of an instance) is always |
| 16413 // instantiated at run time and any bounds were checked during allocation. |
16358 return type_arg.raw(); | 16414 return type_arg.raw(); |
16359 } | 16415 } |
16360 | 16416 |
16361 | 16417 |
16362 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 16418 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
16363 const AbstractType& upper_bound, | 16419 const AbstractType& upper_bound, |
16364 Error* bound_error, | 16420 Error* bound_error, |
| 16421 TrailPtr bound_trail, |
16365 Heap::Space space) const { | 16422 Heap::Space space) const { |
16366 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 16423 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
16367 ASSERT(bounded_type.IsFinalized()); | 16424 ASSERT(bounded_type.IsFinalized()); |
16368 ASSERT(upper_bound.IsFinalized()); | 16425 ASSERT(upper_bound.IsFinalized()); |
16369 ASSERT(!bounded_type.IsMalformed()); | 16426 ASSERT(!bounded_type.IsMalformed()); |
16370 if (bounded_type.IsSubtypeOf(upper_bound, bound_error, space)) { | 16427 if (bounded_type.IsTypeRef() || upper_bound.IsTypeRef()) { |
| 16428 // Shortcut the bound check if the pair <bounded_type, upper_bound> is |
| 16429 // already in the trail. |
| 16430 if (bounded_type.TestAndAddBuddyToTrail(&bound_trail, upper_bound)) { |
| 16431 return true; |
| 16432 } |
| 16433 } |
| 16434 |
| 16435 if (bounded_type.IsSubtypeOf(upper_bound, bound_error, bound_trail, space)) { |
16371 return true; | 16436 return true; |
16372 } | 16437 } |
16373 // Set bound_error if the caller is interested and if this is the first error. | 16438 // Set bound_error if the caller is interested and if this is the first error. |
16374 if ((bound_error != NULL) && bound_error->IsNull()) { | 16439 if ((bound_error != NULL) && bound_error->IsNull()) { |
16375 // Report the bound error only if both the bounded type and the upper bound | 16440 // Report the bound error only if both the bounded type and the upper bound |
16376 // are instantiated. Otherwise, we cannot tell yet it is a bound error. | 16441 // are instantiated. Otherwise, we cannot tell yet it is a bound error. |
16377 if (bounded_type.IsInstantiated() && upper_bound.IsInstantiated()) { | 16442 if (bounded_type.IsInstantiated() && upper_bound.IsInstantiated()) { |
16378 const String& bounded_type_name = String::Handle( | 16443 const String& bounded_type_name = String::Handle( |
16379 bounded_type.UserVisibleName()); | 16444 bounded_type.UserVisibleName()); |
16380 const String& upper_bound_name = String::Handle( | 16445 const String& upper_bound_name = String::Handle( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16417 index(), | 16482 index(), |
16418 String::Handle(name()), | 16483 String::Handle(name()), |
16419 AbstractType::Handle(bound()), | 16484 AbstractType::Handle(bound()), |
16420 token_pos()); | 16485 token_pos()); |
16421 } | 16486 } |
16422 | 16487 |
16423 | 16488 |
16424 RawAbstractType* TypeParameter::CloneUninstantiated( | 16489 RawAbstractType* TypeParameter::CloneUninstantiated( |
16425 const Class& new_owner, TrailPtr trail) const { | 16490 const Class& new_owner, TrailPtr trail) const { |
16426 ASSERT(IsFinalized()); | 16491 ASSERT(IsFinalized()); |
16427 AbstractType& upper_bound = AbstractType::Handle(bound()); | 16492 TypeParameter& clone = TypeParameter::Handle(); |
16428 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | 16493 clone ^= OnlyBuddyInTrail(trail); |
| 16494 if (!clone.IsNull()) { |
| 16495 return clone.raw(); |
| 16496 } |
16429 const Class& old_owner = Class::Handle(parameterized_class()); | 16497 const Class& old_owner = Class::Handle(parameterized_class()); |
16430 const intptr_t new_index = index() + | 16498 const intptr_t new_index = index() + |
16431 new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); | 16499 new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); |
16432 const TypeParameter& clone = TypeParameter::Handle( | 16500 AbstractType& upper_bound = AbstractType::Handle(bound()); |
16433 TypeParameter::New(new_owner, | 16501 clone = TypeParameter::New(new_owner, |
16434 new_index, | 16502 new_index, |
16435 String::Handle(name()), | 16503 String::Handle(name()), |
16436 upper_bound, | 16504 upper_bound, // Not cloned yet. |
16437 token_pos())); | 16505 token_pos()); |
16438 clone.SetIsFinalized(); | 16506 clone.SetIsFinalized(); |
| 16507 AddOnlyBuddyToTrail(&trail, clone); |
| 16508 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); |
| 16509 clone.set_bound(upper_bound); |
16439 return clone.raw(); | 16510 return clone.raw(); |
16440 } | 16511 } |
16441 | 16512 |
16442 | 16513 |
16443 intptr_t TypeParameter::Hash() const { | 16514 intptr_t TypeParameter::Hash() const { |
16444 ASSERT(IsFinalized()); | 16515 ASSERT(IsFinalized()); |
16445 uint32_t result = Class::Handle(parameterized_class()).id(); | 16516 uint32_t result = Class::Handle(parameterized_class()).id(); |
16446 // No need to include the hash of the bound, since the type parameter is fully | 16517 // No need to include the hash of the bound, since the type parameter is fully |
16447 // identified by its class and index. | 16518 // identified by its class and index. |
16448 result = CombineHashes(result, index()); | 16519 result = CombineHashes(result, index()); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16583 // A null type parameter is set when marking a type malformed because of a | 16654 // A null type parameter is set when marking a type malformed because of a |
16584 // bound error at compile time. | 16655 // bound error at compile time. |
16585 ASSERT(value.IsNull() || value.IsFinalized()); | 16656 ASSERT(value.IsNull() || value.IsFinalized()); |
16586 StorePointer(&raw_ptr()->type_parameter_, value.raw()); | 16657 StorePointer(&raw_ptr()->type_parameter_, value.raw()); |
16587 } | 16658 } |
16588 | 16659 |
16589 | 16660 |
16590 RawAbstractType* BoundedType::InstantiateFrom( | 16661 RawAbstractType* BoundedType::InstantiateFrom( |
16591 const TypeArguments& instantiator_type_arguments, | 16662 const TypeArguments& instantiator_type_arguments, |
16592 Error* bound_error, | 16663 Error* bound_error, |
16593 TrailPtr trail, | 16664 TrailPtr instantiation_trail, |
| 16665 TrailPtr bound_trail, |
16594 Heap::Space space) const { | 16666 Heap::Space space) const { |
16595 ASSERT(IsFinalized()); | 16667 ASSERT(IsFinalized()); |
16596 AbstractType& bounded_type = AbstractType::Handle(type()); | 16668 AbstractType& bounded_type = AbstractType::Handle(type()); |
16597 ASSERT(bounded_type.IsFinalized()); | 16669 ASSERT(bounded_type.IsFinalized()); |
| 16670 AbstractType& instantiated_bounded_type = |
| 16671 AbstractType::Handle(bounded_type.raw()); |
16598 if (!bounded_type.IsInstantiated()) { | 16672 if (!bounded_type.IsInstantiated()) { |
16599 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, | 16673 instantiated_bounded_type = |
16600 bound_error, | 16674 bounded_type.InstantiateFrom(instantiator_type_arguments, |
16601 trail, | 16675 bound_error, |
16602 space); | 16676 instantiation_trail, |
16603 // In case types of instantiator_type_arguments are not finalized, then | 16677 bound_trail, |
16604 // the instantiated bounded_type is not finalized either. | 16678 space); |
| 16679 // In case types of instantiator_type_arguments are not finalized |
| 16680 // (or instantiated), then the instantiated_bounded_type is not finalized |
| 16681 // (or instantiated) either. |
16605 // Note that instantiator_type_arguments must have the final length, though. | 16682 // Note that instantiator_type_arguments must have the final length, though. |
16606 } | 16683 } |
16607 if ((Isolate::Current()->flags().type_checks()) && | 16684 if ((Isolate::Current()->flags().type_checks()) && |
16608 (bound_error != NULL) && bound_error->IsNull()) { | 16685 (bound_error != NULL) && bound_error->IsNull()) { |
16609 AbstractType& upper_bound = AbstractType::Handle(bound()); | 16686 AbstractType& upper_bound = AbstractType::Handle(bound()); |
16610 ASSERT(upper_bound.IsFinalized()); | 16687 ASSERT(upper_bound.IsFinalized()); |
16611 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); | 16688 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); |
16612 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 16689 AbstractType& instantiated_upper_bound = |
| 16690 AbstractType::Handle(upper_bound.raw()); |
16613 if (!upper_bound.IsInstantiated()) { | 16691 if (!upper_bound.IsInstantiated()) { |
16614 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, | 16692 instantiated_upper_bound = |
16615 bound_error, | 16693 upper_bound.InstantiateFrom(instantiator_type_arguments, |
16616 trail, | 16694 bound_error, |
16617 space); | 16695 instantiation_trail, |
16618 // Instantiated upper_bound may not be finalized. See comment above. | 16696 bound_trail, |
| 16697 space); |
| 16698 // The instantiated_upper_bound may not be finalized or instantiated. |
| 16699 // See comment above. |
16619 } | 16700 } |
16620 if (bound_error->IsNull()) { | 16701 if (bound_error->IsNull()) { |
16621 if (bounded_type.IsBeingFinalized() || | 16702 // Shortcut the F-bounded case where we have reached a fixpoint. |
16622 upper_bound.IsBeingFinalized() || | 16703 if (instantiated_bounded_type.Equals(bounded_type) && |
16623 (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && | 16704 instantiated_upper_bound.Equals(upper_bound)) { |
| 16705 return bounded_type.raw(); |
| 16706 } |
| 16707 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
| 16708 if (instantiated_bounded_type.IsBeingFinalized() || |
| 16709 instantiated_upper_bound.IsBeingFinalized() || |
| 16710 (!type_param.CheckBound(instantiated_bounded_type, |
| 16711 instantiated_upper_bound, |
| 16712 bound_error, |
| 16713 bound_trail) && |
16624 bound_error->IsNull())) { | 16714 bound_error->IsNull())) { |
16625 // We cannot determine yet whether the bounded_type is below the | 16715 // We cannot determine yet whether the bounded_type is below the |
16626 // upper_bound, because one or both of them is still being finalized or | 16716 // upper_bound, because one or both of them is still being finalized or |
16627 // uninstantiated. | 16717 // uninstantiated. |
16628 ASSERT(bounded_type.IsBeingFinalized() || | 16718 ASSERT(instantiated_bounded_type.IsBeingFinalized() || |
16629 upper_bound.IsBeingFinalized() || | 16719 instantiated_upper_bound.IsBeingFinalized() || |
16630 !bounded_type.IsInstantiated() || | 16720 !instantiated_bounded_type.IsInstantiated() || |
16631 !upper_bound.IsInstantiated()); | 16721 !instantiated_upper_bound.IsInstantiated()); |
16632 // Postpone bound check by returning a new BoundedType with unfinalized | 16722 // Postpone bound check by returning a new BoundedType with unfinalized |
16633 // or partially instantiated bounded_type and upper_bound, but keeping | 16723 // or partially instantiated bounded_type and upper_bound, but keeping |
16634 // type_param. | 16724 // type_param. |
16635 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); | 16725 instantiated_bounded_type = BoundedType::New(instantiated_bounded_type, |
| 16726 instantiated_upper_bound, |
| 16727 type_param); |
16636 } | 16728 } |
16637 } | 16729 } |
16638 } | 16730 } |
16639 return bounded_type.raw(); | 16731 return instantiated_bounded_type.raw(); |
16640 } | 16732 } |
16641 | 16733 |
16642 | 16734 |
16643 RawAbstractType* BoundedType::CloneUnfinalized() const { | 16735 RawAbstractType* BoundedType::CloneUnfinalized() const { |
16644 if (IsFinalized()) { | 16736 if (IsFinalized()) { |
16645 return raw(); | 16737 return raw(); |
16646 } | 16738 } |
16647 AbstractType& bounded_type = AbstractType::Handle(type()); | 16739 AbstractType& bounded_type = AbstractType::Handle(type()); |
16648 | 16740 |
16649 bounded_type = bounded_type.CloneUnfinalized(); | 16741 bounded_type = bounded_type.CloneUnfinalized(); |
(...skipping 4726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21376 return UserTag::null(); | 21468 return UserTag::null(); |
21377 } | 21469 } |
21378 | 21470 |
21379 | 21471 |
21380 const char* UserTag::ToCString() const { | 21472 const char* UserTag::ToCString() const { |
21381 const String& tag_label = String::Handle(label()); | 21473 const String& tag_label = String::Handle(label()); |
21382 return tag_label.ToCString(); | 21474 return tag_label.ToCString(); |
21383 } | 21475 } |
21384 | 21476 |
21385 } // namespace dart | 21477 } // namespace dart |
OLD | NEW |