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 ASSERT(IsOld()); | |
rmacnak
2016/02/09 00:50:22
I don't like the IsOld assertions. The type system
regis
2016/02/09 17:17:38
Unfortunately, the type system does care. If you l
rmacnak
2016/02/09 18:11:20
I mean everything should still work if we didn't p
| |
4839 return this->raw(); | |
4840 } | |
4818 SetTypeAt(i, type_arg); | 4841 SetTypeAt(i, type_arg); |
4819 } | 4842 } |
4820 // Canonicalization of a recursive type may change its hash. | 4843 // Canonicalization of a recursive type may change its hash. |
4821 intptr_t canonical_hash = hash; | 4844 intptr_t canonical_hash = hash; |
4822 if (IsRecursive()) { | 4845 if (IsRecursive()) { |
4823 canonical_hash = Hash(); | 4846 canonical_hash = Hash(); |
4824 } | 4847 } |
4825 // Canonicalization of the type argument's own type arguments may add an | 4848 // 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 | 4849 // entry to the table, or even grow the table, and thereby change the |
4827 // previously calculated index. | 4850 // previously calculated index. |
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5920 intptr_t parameter_position, | 5943 intptr_t parameter_position, |
5921 intptr_t other_parameter_position, | 5944 intptr_t other_parameter_position, |
5922 const TypeArguments& type_arguments, | 5945 const TypeArguments& type_arguments, |
5923 const Function& other, | 5946 const Function& other, |
5924 const TypeArguments& other_type_arguments, | 5947 const TypeArguments& other_type_arguments, |
5925 Error* bound_error, | 5948 Error* bound_error, |
5926 Heap::Space space) const { | 5949 Heap::Space space) const { |
5927 AbstractType& other_param_type = | 5950 AbstractType& other_param_type = |
5928 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); | 5951 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); |
5929 if (!other_param_type.IsInstantiated()) { | 5952 if (!other_param_type.IsInstantiated()) { |
5930 other_param_type = other_param_type.InstantiateFrom(other_type_arguments, | 5953 other_param_type = |
5931 bound_error, | 5954 other_param_type.InstantiateFrom(other_type_arguments, |
5932 NULL, // trail | 5955 bound_error, |
5933 space); | 5956 NULL, // instantiation_trail |
5957 NULL, // bound_trail | |
5958 space); | |
5934 ASSERT((bound_error == NULL) || bound_error->IsNull()); | 5959 ASSERT((bound_error == NULL) || bound_error->IsNull()); |
5935 } | 5960 } |
5936 if (other_param_type.IsDynamicType()) { | 5961 if (other_param_type.IsDynamicType()) { |
5937 return true; | 5962 return true; |
5938 } | 5963 } |
5939 AbstractType& param_type = | 5964 AbstractType& param_type = |
5940 AbstractType::Handle(ParameterTypeAt(parameter_position)); | 5965 AbstractType::Handle(ParameterTypeAt(parameter_position)); |
5941 if (!param_type.IsInstantiated()) { | 5966 if (!param_type.IsInstantiated()) { |
5942 param_type = param_type.InstantiateFrom( | 5967 param_type = param_type.InstantiateFrom(type_arguments, |
5943 type_arguments, bound_error, NULL /*trail*/, space); | 5968 bound_error, |
5969 NULL, // instantiation_trail | |
5970 NULL, // bound_trail | |
5971 space); | |
5944 ASSERT((bound_error == NULL) || bound_error->IsNull()); | 5972 ASSERT((bound_error == NULL) || bound_error->IsNull()); |
5945 } | 5973 } |
5946 if (param_type.IsDynamicType()) { | 5974 if (param_type.IsDynamicType()) { |
5947 return test_kind == kIsSubtypeOf; | 5975 return test_kind == kIsSubtypeOf; |
5948 } | 5976 } |
5949 if (test_kind == kIsSubtypeOf) { | 5977 if (test_kind == kIsSubtypeOf) { |
5950 if (!param_type.IsSubtypeOf(other_param_type, bound_error, space) && | 5978 if (!param_type.IsSubtypeOf(other_param_type, bound_error, NULL, space) && |
5951 !other_param_type.IsSubtypeOf(param_type, bound_error, space)) { | 5979 !other_param_type.IsSubtypeOf(param_type, bound_error, NULL, space)) { |
5952 return false; | 5980 return false; |
5953 } | 5981 } |
5954 } else { | 5982 } else { |
5955 ASSERT(test_kind == kIsMoreSpecificThan); | 5983 ASSERT(test_kind == kIsMoreSpecificThan); |
5956 if (!param_type.IsMoreSpecificThan(other_param_type, bound_error, space)) { | 5984 if (!param_type.IsMoreSpecificThan( |
5985 other_param_type, bound_error, NULL, space)) { | |
5957 return false; | 5986 return false; |
5958 } | 5987 } |
5959 } | 5988 } |
5960 return true; | 5989 return true; |
5961 } | 5990 } |
5962 | 5991 |
5963 | 5992 |
5964 bool Function::TypeTest(TypeTestKind test_kind, | 5993 bool Function::TypeTest(TypeTestKind test_kind, |
5965 const TypeArguments& type_arguments, | 5994 const TypeArguments& type_arguments, |
5966 const Function& other, | 5995 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); | 6398 ASSERT((num_fixed_params + num_opt_params) == num_params); |
6370 intptr_t i = 0; | 6399 intptr_t i = 0; |
6371 if (name_visibility == kUserVisibleName) { | 6400 if (name_visibility == kUserVisibleName) { |
6372 // Hide implicit parameters. | 6401 // Hide implicit parameters. |
6373 i = NumImplicitParameters(); | 6402 i = NumImplicitParameters(); |
6374 } | 6403 } |
6375 String& name = String::Handle(zone); | 6404 String& name = String::Handle(zone); |
6376 while (i < num_fixed_params) { | 6405 while (i < num_fixed_params) { |
6377 param_type = ParameterTypeAt(i); | 6406 param_type = ParameterTypeAt(i); |
6378 ASSERT(!param_type.IsNull()); | 6407 ASSERT(!param_type.IsNull()); |
6379 if (instantiate && !param_type.IsInstantiated()) { | 6408 if (instantiate && |
6409 param_type.IsFinalized() && | |
6410 !param_type.IsInstantiated()) { | |
6380 param_type = param_type.InstantiateFrom(instantiator, NULL); | 6411 param_type = param_type.InstantiateFrom(instantiator, NULL); |
6381 } | 6412 } |
6382 name = param_type.BuildName(name_visibility); | 6413 name = param_type.BuildName(name_visibility); |
6383 pieces->Add(name); | 6414 pieces->Add(name); |
6384 if (i != (num_params - 1)) { | 6415 if (i != (num_params - 1)) { |
6385 pieces->Add(Symbols::CommaSpace()); | 6416 pieces->Add(Symbols::CommaSpace()); |
6386 } | 6417 } |
6387 i++; | 6418 i++; |
6388 } | 6419 } |
6389 if (num_opt_params > 0) { | 6420 if (num_opt_params > 0) { |
6390 if (num_opt_pos_params > 0) { | 6421 if (num_opt_pos_params > 0) { |
6391 pieces->Add(Symbols::LBracket()); | 6422 pieces->Add(Symbols::LBracket()); |
6392 } else { | 6423 } else { |
6393 pieces->Add(Symbols::LBrace()); | 6424 pieces->Add(Symbols::LBrace()); |
6394 } | 6425 } |
6395 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 6426 for (intptr_t i = num_fixed_params; i < num_params; i++) { |
6396 // The parameter name of an optional positional parameter does not need | 6427 // The parameter name of an optional positional parameter does not need |
6397 // to be part of the signature, since it is not used. | 6428 // to be part of the signature, since it is not used. |
6398 if (num_opt_named_params > 0) { | 6429 if (num_opt_named_params > 0) { |
6399 name = ParameterNameAt(i); | 6430 name = ParameterNameAt(i); |
6400 pieces->Add(name); | 6431 pieces->Add(name); |
6401 pieces->Add(Symbols::ColonSpace()); | 6432 pieces->Add(Symbols::ColonSpace()); |
6402 } | 6433 } |
6403 param_type = ParameterTypeAt(i); | 6434 param_type = ParameterTypeAt(i); |
6404 if (instantiate && !param_type.IsInstantiated()) { | 6435 if (instantiate && |
6436 param_type.IsFinalized() && | |
6437 !param_type.IsInstantiated()) { | |
6405 param_type = param_type.InstantiateFrom(instantiator, NULL); | 6438 param_type = param_type.InstantiateFrom(instantiator, NULL); |
6406 } | 6439 } |
6407 ASSERT(!param_type.IsNull()); | 6440 ASSERT(!param_type.IsNull()); |
6408 name = param_type.BuildName(name_visibility); | 6441 name = param_type.BuildName(name_visibility); |
6409 pieces->Add(name); | 6442 pieces->Add(name); |
6410 if (i != (num_params - 1)) { | 6443 if (i != (num_params - 1)) { |
6411 pieces->Add(Symbols::CommaSpace()); | 6444 pieces->Add(Symbols::CommaSpace()); |
6412 } | 6445 } |
6413 } | 6446 } |
6414 if (num_opt_pos_params > 0) { | 6447 if (num_opt_pos_params > 0) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6492 pieces.Add(Symbols::RAngleBracket()); | 6525 pieces.Add(Symbols::RAngleBracket()); |
6493 } | 6526 } |
6494 } | 6527 } |
6495 pieces.Add(Symbols::LParen()); | 6528 pieces.Add(Symbols::LParen()); |
6496 BuildSignatureParameters(instantiate, | 6529 BuildSignatureParameters(instantiate, |
6497 name_visibility, | 6530 name_visibility, |
6498 instantiator, | 6531 instantiator, |
6499 &pieces); | 6532 &pieces); |
6500 pieces.Add(Symbols::RParenArrow()); | 6533 pieces.Add(Symbols::RParenArrow()); |
6501 AbstractType& res_type = AbstractType::Handle(zone, result_type()); | 6534 AbstractType& res_type = AbstractType::Handle(zone, result_type()); |
6502 if (instantiate && !res_type.IsInstantiated()) { | 6535 if (instantiate && res_type.IsFinalized() && !res_type.IsInstantiated()) { |
6503 res_type = res_type.InstantiateFrom(instantiator, NULL); | 6536 res_type = res_type.InstantiateFrom(instantiator, NULL); |
6504 } | 6537 } |
6505 name = res_type.BuildName(name_visibility); | 6538 name = res_type.BuildName(name_visibility); |
6506 pieces.Add(name); | 6539 pieces.Add(name); |
6507 return Symbols::FromConcatAll(pieces); | 6540 return Symbols::FromConcatAll(pieces); |
6508 } | 6541 } |
6509 | 6542 |
6510 | 6543 |
6511 bool Function::HasInstantiatedSignature() const { | 6544 bool Function::HasInstantiatedSignature() const { |
6512 AbstractType& type = AbstractType::Handle(result_type()); | 6545 AbstractType& type = AbstractType::Handle(result_type()); |
(...skipping 7749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14262 Heap::kOld)) { | 14295 Heap::kOld)) { |
14263 return true; | 14296 return true; |
14264 } | 14297 } |
14265 } | 14298 } |
14266 } | 14299 } |
14267 if (!instantiated_other.IsType()) { | 14300 if (!instantiated_other.IsType()) { |
14268 return false; | 14301 return false; |
14269 } | 14302 } |
14270 other_class = instantiated_other.type_class(); | 14303 other_class = instantiated_other.type_class(); |
14271 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, | 14304 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |
14272 bound_error, Heap::kOld); | 14305 bound_error, NULL, Heap::kOld); |
14273 } | 14306 } |
14274 | 14307 |
14275 | 14308 |
14276 bool Instance::OperatorEquals(const Instance& other) const { | 14309 bool Instance::OperatorEquals(const Instance& other) const { |
14277 // TODO(koda): Optimize for all builtin classes and all classes | 14310 // TODO(koda): Optimize for all builtin classes and all classes |
14278 // that do not override operator==. | 14311 // that do not override operator==. |
14279 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); | 14312 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); |
14280 } | 14313 } |
14281 | 14314 |
14282 | 14315 |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14589 bool AbstractType::IsRecursive() const { | 14622 bool AbstractType::IsRecursive() const { |
14590 // AbstractType is an abstract class. | 14623 // AbstractType is an abstract class. |
14591 UNREACHABLE(); | 14624 UNREACHABLE(); |
14592 return false; | 14625 return false; |
14593 } | 14626 } |
14594 | 14627 |
14595 | 14628 |
14596 RawAbstractType* AbstractType::InstantiateFrom( | 14629 RawAbstractType* AbstractType::InstantiateFrom( |
14597 const TypeArguments& instantiator_type_arguments, | 14630 const TypeArguments& instantiator_type_arguments, |
14598 Error* bound_error, | 14631 Error* bound_error, |
14599 TrailPtr trail, | 14632 TrailPtr instantiation_trail, |
14633 TrailPtr bound_trail, | |
14600 Heap::Space space) const { | 14634 Heap::Space space) const { |
14601 // AbstractType is an abstract class. | 14635 // AbstractType is an abstract class. |
14602 UNREACHABLE(); | 14636 UNREACHABLE(); |
14603 return NULL; | 14637 return NULL; |
14604 } | 14638 } |
14605 | 14639 |
14606 | 14640 |
14607 RawAbstractType* AbstractType::CloneUnfinalized() const { | 14641 RawAbstractType* AbstractType::CloneUnfinalized() const { |
14608 // AbstractType is an abstract class. | 14642 // AbstractType is an abstract class. |
14609 UNREACHABLE(); | 14643 UNREACHABLE(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14649 if (*trail == NULL) { | 14683 if (*trail == NULL) { |
14650 *trail = new Trail(Thread::Current()->zone(), 4); | 14684 *trail = new Trail(Thread::Current()->zone(), 4); |
14651 } else { | 14685 } else { |
14652 ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); | 14686 ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); |
14653 } | 14687 } |
14654 (*trail)->Add(*this); | 14688 (*trail)->Add(*this); |
14655 (*trail)->Add(buddy); | 14689 (*trail)->Add(buddy); |
14656 } | 14690 } |
14657 | 14691 |
14658 | 14692 |
14693 bool AbstractType::TestAndAddToTrail(TrailPtr* trail) const { | |
14694 if (*trail == NULL) { | |
14695 *trail = new Trail(Thread::Current()->zone(), 4); | |
14696 } else { | |
14697 const intptr_t len = (*trail)->length(); | |
14698 for (intptr_t i = 0; i < len; i++) { | |
14699 if ((*trail)->At(i).raw() == this->raw()) { | |
14700 return true; | |
14701 } | |
14702 } | |
14703 } | |
14704 (*trail)->Add(*this); | |
14705 return false; | |
14706 } | |
14707 | |
14708 | |
14709 bool AbstractType::TestAndAddBuddyToTrail(TrailPtr* trail, | |
14710 const AbstractType& buddy) const { | |
14711 if (*trail == NULL) { | |
14712 *trail = new Trail(Thread::Current()->zone(), 4); | |
14713 } else { | |
14714 const intptr_t len = (*trail)->length(); | |
14715 ASSERT((len % 2) == 0); | |
14716 const bool this_is_typeref = IsTypeRef(); | |
14717 const bool buddy_is_typeref = buddy.IsTypeRef(); | |
14718 ASSERT(this_is_typeref || buddy_is_typeref); | |
14719 for (intptr_t i = 0; i < len; i += 2) { | |
14720 if ((((*trail)->At(i).raw() == this->raw()) || | |
14721 (buddy_is_typeref && (*trail)->At(i).Equals(*this))) && | |
14722 (((*trail)->At(i + 1).raw() == buddy.raw()) || | |
14723 (this_is_typeref && (*trail)->At(i + 1).Equals(buddy)))) { | |
14724 return true; | |
14725 } | |
14726 } | |
14727 } | |
14728 (*trail)->Add(*this); | |
14729 (*trail)->Add(buddy); | |
14730 return false; | |
14731 } | |
14732 | |
14733 | |
14659 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 14734 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
14660 Zone* zone = Thread::Current()->zone(); | 14735 Zone* zone = Thread::Current()->zone(); |
14661 if (IsBoundedType()) { | 14736 if (IsBoundedType()) { |
14662 const AbstractType& type = AbstractType::Handle( | 14737 const AbstractType& type = AbstractType::Handle( |
14663 BoundedType::Cast(*this).type()); | 14738 BoundedType::Cast(*this).type()); |
14664 if (name_visibility == kPrettyName) { | 14739 if (name_visibility == kPrettyName) { |
14665 return type.BuildName(kPrettyName); | 14740 return type.BuildName(kPrettyName); |
14666 } else if (name_visibility == kUserVisibleName) { | 14741 } else if (name_visibility == kUserVisibleName) { |
14667 return type.BuildName(kUserVisibleName); | 14742 return type.BuildName(kUserVisibleName); |
14668 } | 14743 } |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14855 | 14930 |
14856 bool AbstractType::IsDartFunctionType() const { | 14931 bool AbstractType::IsDartFunctionType() const { |
14857 return HasResolvedTypeClass() && | 14932 return HasResolvedTypeClass() && |
14858 (type_class() == Type::Handle(Type::Function()).type_class()); | 14933 (type_class() == Type::Handle(Type::Function()).type_class()); |
14859 } | 14934 } |
14860 | 14935 |
14861 | 14936 |
14862 bool AbstractType::TypeTest(TypeTestKind test_kind, | 14937 bool AbstractType::TypeTest(TypeTestKind test_kind, |
14863 const AbstractType& other, | 14938 const AbstractType& other, |
14864 Error* bound_error, | 14939 Error* bound_error, |
14940 TrailPtr bound_trail, | |
14865 Heap::Space space) const { | 14941 Heap::Space space) const { |
14866 ASSERT(IsFinalized()); | 14942 ASSERT(IsFinalized()); |
14867 ASSERT(other.IsFinalized()); | 14943 ASSERT(other.IsFinalized()); |
14868 if (IsMalformed() || other.IsMalformed()) { | 14944 if (IsMalformed() || other.IsMalformed()) { |
14869 // Malformed types involved in subtype tests should be handled specially | 14945 // Malformed types involved in subtype tests should be handled specially |
14870 // by the caller. Malformed types should only be encountered here in a | 14946 // by the caller. Malformed types should only be encountered here in a |
14871 // more specific than test. | 14947 // more specific than test. |
14872 ASSERT(test_kind == kIsMoreSpecificThan); | 14948 ASSERT(test_kind == kIsMoreSpecificThan); |
14873 return false; | 14949 return false; |
14874 } | 14950 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14925 if (type_param.Equals(other_type_param)) { | 15001 if (type_param.Equals(other_type_param)) { |
14926 return true; | 15002 return true; |
14927 } | 15003 } |
14928 } | 15004 } |
14929 const AbstractType& bound = AbstractType::Handle(zone, type_param.bound()); | 15005 const AbstractType& bound = AbstractType::Handle(zone, type_param.bound()); |
14930 // We may be checking bounds at finalization time and can encounter | 15006 // We may be checking bounds at finalization time and can encounter |
14931 // a still unfinalized bound. Finalizing the bound here may lead to cycles. | 15007 // a still unfinalized bound. Finalizing the bound here may lead to cycles. |
14932 if (!bound.IsFinalized()) { | 15008 if (!bound.IsFinalized()) { |
14933 return false; // TODO(regis): Return "maybe after instantiation". | 15009 return false; // TODO(regis): Return "maybe after instantiation". |
14934 } | 15010 } |
14935 if (bound.IsMoreSpecificThan(other, bound_error)) { | 15011 // The current bound_trail cannot be used, because operands are swapped and |
15012 // the test is different anyway (more specific vs. subtype). | |
15013 if (bound.IsMoreSpecificThan(other, bound_error, NULL)) { | |
14936 return true; | 15014 return true; |
14937 } | 15015 } |
14938 return false; // TODO(regis): We should return "maybe after instantiation". | 15016 return false; // TODO(regis): We should return "maybe after instantiation". |
14939 } | 15017 } |
14940 if (other.IsTypeParameter()) { | 15018 if (other.IsTypeParameter()) { |
14941 return false; // TODO(regis): We should return "maybe after instantiation". | 15019 return false; // TODO(regis): We should return "maybe after instantiation". |
14942 } | 15020 } |
14943 const Class& type_cls = Class::Handle(zone, type_class()); | 15021 const Class& type_cls = Class::Handle(zone, type_class()); |
14944 // Function types cannot be handled by Class::TypeTest(). | 15022 // Function types cannot be handled by Class::TypeTest(). |
14945 const bool other_is_dart_function_type = other.IsDartFunctionType(); | 15023 const bool other_is_dart_function_type = other.IsDartFunctionType(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14985 } | 15063 } |
14986 } | 15064 } |
14987 if (IsFunctionType()) { | 15065 if (IsFunctionType()) { |
14988 return false; | 15066 return false; |
14989 } | 15067 } |
14990 return type_cls.TypeTest(test_kind, | 15068 return type_cls.TypeTest(test_kind, |
14991 TypeArguments::Handle(zone, arguments()), | 15069 TypeArguments::Handle(zone, arguments()), |
14992 Class::Handle(zone, other.type_class()), | 15070 Class::Handle(zone, other.type_class()), |
14993 TypeArguments::Handle(zone, other.arguments()), | 15071 TypeArguments::Handle(zone, other.arguments()), |
14994 bound_error, | 15072 bound_error, |
15073 bound_trail, | |
14995 space); | 15074 space); |
14996 } | 15075 } |
14997 | 15076 |
14998 | 15077 |
14999 intptr_t AbstractType::Hash() const { | 15078 intptr_t AbstractType::Hash() const { |
15000 // AbstractType is an abstract class. | 15079 // AbstractType is an abstract class. |
15001 UNREACHABLE(); | 15080 UNREACHABLE(); |
15002 return 0; | 15081 return 0; |
15003 } | 15082 } |
15004 | 15083 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15229 num_type_args = len; | 15308 num_type_args = len; |
15230 len = cls.NumTypeParameters(); // Check the type parameters only. | 15309 len = cls.NumTypeParameters(); // Check the type parameters only. |
15231 } | 15310 } |
15232 return (len == 0) || args.IsSubvectorInstantiated(num_type_args - len, len); | 15311 return (len == 0) || args.IsSubvectorInstantiated(num_type_args - len, len); |
15233 } | 15312 } |
15234 | 15313 |
15235 | 15314 |
15236 RawAbstractType* Type::InstantiateFrom( | 15315 RawAbstractType* Type::InstantiateFrom( |
15237 const TypeArguments& instantiator_type_arguments, | 15316 const TypeArguments& instantiator_type_arguments, |
15238 Error* bound_error, | 15317 Error* bound_error, |
15239 TrailPtr trail, | 15318 TrailPtr instantiation_trail, |
15319 TrailPtr bound_trail, | |
15240 Heap::Space space) const { | 15320 Heap::Space space) const { |
15241 Zone* zone = Thread::Current()->zone(); | 15321 Zone* zone = Thread::Current()->zone(); |
15242 ASSERT(IsFinalized() || IsBeingFinalized()); | 15322 ASSERT(IsFinalized() || IsBeingFinalized()); |
15243 ASSERT(!IsInstantiated()); | 15323 ASSERT(!IsInstantiated()); |
15244 // Return the uninstantiated type unchanged if malformed. No copy needed. | 15324 // Return the uninstantiated type unchanged if malformed. No copy needed. |
15245 if (IsMalformed()) { | 15325 if (IsMalformed()) { |
15246 return raw(); | 15326 return raw(); |
15247 } | 15327 } |
15248 // Instantiating this type with its own type arguments as instantiator can | 15328 // Instantiating this type with its own type arguments as instantiator can |
15249 // occur during finalization and bounds checking. Return the type unchanged. | 15329 // occur during finalization and bounds checking. Return the type unchanged. |
15250 if (arguments() == instantiator_type_arguments.raw()) { | 15330 if (arguments() == instantiator_type_arguments.raw()) { |
15251 return raw(); | 15331 return raw(); |
15252 } | 15332 } |
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 | 15333 // 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 | 15334 // necessarily finalized yet. We may be checking bounds at compile time or |
15262 // finalizing the type argument vector of a recursive type. | 15335 // finalizing the type argument vector of a recursive type. |
15263 const Class& cls = Class::Handle(zone, type_class()); | 15336 const Class& cls = Class::Handle(zone, type_class()); |
15264 | 15337 TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments()); |
15338 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); | |
15339 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | |
15340 bound_error, | |
15341 instantiation_trail, | |
15342 bound_trail, | |
15343 space); | |
15265 // This uninstantiated type is not modified, as it can be instantiated | 15344 // This uninstantiated type is not modified, as it can be instantiated |
15266 // with different instantiators. Allocate a new instantiated version of it. | 15345 // with different instantiators. Allocate a new instantiated version of it. |
15267 instantiated_type = | 15346 const Type& instantiated_type = |
15268 Type::New(cls, TypeArguments::Handle(zone), token_pos(), space); | 15347 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()) { | 15348 if (IsFinalized()) { |
15280 instantiated_type.SetIsFinalized(); | 15349 instantiated_type.SetIsFinalized(); |
15281 } else { | 15350 } else { |
15282 instantiated_type.SetIsResolved(); | 15351 instantiated_type.SetIsResolved(); |
15283 } | 15352 } |
15284 // Canonicalization is not part of instantiation. | 15353 // Canonicalization is not part of instantiation. |
15285 return instantiated_type.raw(); | 15354 return instantiated_type.raw(); |
15286 } | 15355 } |
15287 | 15356 |
15288 | 15357 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15432 return Object::dynamic_type().raw(); | 15501 return Object::dynamic_type().raw(); |
15433 } | 15502 } |
15434 // Fast canonical lookup/registry for simple types. | 15503 // Fast canonical lookup/registry for simple types. |
15435 if (!cls.IsGeneric() && !cls.IsClosureClass()) { | 15504 if (!cls.IsGeneric() && !cls.IsClosureClass()) { |
15436 type = cls.CanonicalType(); | 15505 type = cls.CanonicalType(); |
15437 if (type.IsNull()) { | 15506 if (type.IsNull()) { |
15438 ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate())); | 15507 ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate())); |
15439 // Canonicalize the type arguments of the supertype, if any. | 15508 // Canonicalize the type arguments of the supertype, if any. |
15440 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 15509 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
15441 type_args = type_args.Canonicalize(trail); | 15510 type_args = type_args.Canonicalize(trail); |
15511 if (IsCanonical()) { | |
15512 // Canonicalizing type_args canonicalized this type. | |
15513 ASSERT(IsRecursive()); | |
15514 ASSERT(IsOld()); | |
15515 return this->raw(); | |
15516 } | |
15442 set_arguments(type_args); | 15517 set_arguments(type_args); |
15443 type = cls.CanonicalType(); // May be set while canonicalizing type args. | 15518 type = cls.CanonicalType(); // May be set while canonicalizing type args. |
15444 if (type.IsNull()) { | 15519 if (type.IsNull()) { |
15445 cls.set_canonical_types(*this); | 15520 cls.set_canonical_types(*this); |
15446 SetCanonical(); | 15521 SetCanonical(); |
15447 return this->raw(); | 15522 return this->raw(); |
15448 } | 15523 } |
15449 } | 15524 } |
15450 ASSERT(this->Equals(type)); | 15525 ASSERT(this->Equals(type)); |
15451 ASSERT(type.IsCanonical()); | 15526 ASSERT(type.IsCanonical()); |
(...skipping 24 matching lines...) Expand all Loading... | |
15476 index++; | 15551 index++; |
15477 } | 15552 } |
15478 // The type was not found in the table. It is not canonical yet. | 15553 // The type was not found in the table. It is not canonical yet. |
15479 | 15554 |
15480 // Canonicalize the type arguments. | 15555 // Canonicalize the type arguments. |
15481 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 15556 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
15482 // In case the type is first canonicalized at runtime, its type argument | 15557 // In case the type is first canonicalized at runtime, its type argument |
15483 // vector may be longer than necessary. This is not an issue. | 15558 // vector may be longer than necessary. This is not an issue. |
15484 ASSERT(type_args.IsNull() || (type_args.Length() >= cls.NumTypeArguments())); | 15559 ASSERT(type_args.IsNull() || (type_args.Length() >= cls.NumTypeArguments())); |
15485 type_args = type_args.Canonicalize(trail); | 15560 type_args = type_args.Canonicalize(trail); |
15561 if (IsCanonical()) { | |
15562 // Canonicalizing type_args canonicalized this type as a side effect. | |
15563 ASSERT(IsRecursive()); | |
15564 ASSERT(IsOld()); | |
15565 return this->raw(); | |
15566 } | |
15486 set_arguments(type_args); | 15567 set_arguments(type_args); |
15487 | 15568 |
15488 // Canonicalizing the type arguments may have changed the index, may have | 15569 // Canonicalizing the type arguments may have changed the index, may have |
15489 // grown the table, or may even have canonicalized this type. | 15570 // grown the table, or may even have canonicalized this type. |
15490 canonical_types ^= cls.canonical_types(); | 15571 canonical_types ^= cls.canonical_types(); |
15491 if (canonical_types.IsNull()) { | 15572 if (canonical_types.IsNull()) { |
15492 canonical_types = empty_array().raw(); | 15573 canonical_types = empty_array().raw(); |
15493 } | 15574 } |
15494 length = canonical_types.Length(); | 15575 length = canonical_types.Length(); |
15495 while (index < length) { | 15576 while (index < length) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15534 } | 15615 } |
15535 | 15616 |
15536 | 15617 |
15537 void Type::set_type_class(const Object& value) const { | 15618 void Type::set_type_class(const Object& value) const { |
15538 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); | 15619 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); |
15539 StorePointer(&raw_ptr()->type_class_, value.raw()); | 15620 StorePointer(&raw_ptr()->type_class_, value.raw()); |
15540 } | 15621 } |
15541 | 15622 |
15542 | 15623 |
15543 void Type::set_arguments(const TypeArguments& value) const { | 15624 void Type::set_arguments(const TypeArguments& value) const { |
15625 ASSERT(!IsCanonical()); | |
15544 StorePointer(&raw_ptr()->arguments_, value.raw()); | 15626 StorePointer(&raw_ptr()->arguments_, value.raw()); |
15545 } | 15627 } |
15546 | 15628 |
15547 | 15629 |
15548 RawType* Type::New(Heap::Space space) { | 15630 RawType* Type::New(Heap::Space space) { |
15549 RawObject* raw = Object::Allocate(Type::kClassId, | 15631 RawObject* raw = Object::Allocate(Type::kClassId, |
15550 Type::InstanceSize(), | 15632 Type::InstanceSize(), |
15551 space); | 15633 space); |
15552 return reinterpret_cast<RawType*>(raw); | 15634 return reinterpret_cast<RawType*>(raw); |
15553 } | 15635 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15698 return | 15780 return |
15699 (num_type_params == 0) || | 15781 (num_type_params == 0) || |
15700 type_arguments.IsSubvectorInstantiated(num_type_args - num_type_params, | 15782 type_arguments.IsSubvectorInstantiated(num_type_args - num_type_params, |
15701 num_type_params); | 15783 num_type_params); |
15702 } | 15784 } |
15703 | 15785 |
15704 | 15786 |
15705 RawAbstractType* FunctionType::InstantiateFrom( | 15787 RawAbstractType* FunctionType::InstantiateFrom( |
15706 const TypeArguments& instantiator_type_arguments, | 15788 const TypeArguments& instantiator_type_arguments, |
15707 Error* bound_error, | 15789 Error* bound_error, |
15708 TrailPtr trail, | 15790 TrailPtr instantiation_trail, |
15791 TrailPtr bound_trail, | |
15709 Heap::Space space) const { | 15792 Heap::Space space) const { |
15710 Zone* zone = Thread::Current()->zone(); | 15793 Zone* zone = Thread::Current()->zone(); |
15711 ASSERT(IsFinalized() || IsBeingFinalized()); | 15794 ASSERT(IsFinalized() || IsBeingFinalized()); |
15712 ASSERT(!IsInstantiated()); | 15795 ASSERT(!IsInstantiated()); |
15713 ASSERT(!IsMalformed()); // FunctionType cannot be malformed. | 15796 ASSERT(!IsMalformed()); // FunctionType cannot be malformed. |
15714 // Instantiating this type with its own type arguments as instantiator can | 15797 // Instantiating this type with its own type arguments as instantiator can |
15715 // occur during finalization and bounds checking. Return the type unchanged. | 15798 // occur during finalization and bounds checking. Return the type unchanged. |
15716 if (arguments() == instantiator_type_arguments.raw()) { | 15799 if (arguments() == instantiator_type_arguments.raw()) { |
15717 return raw(); | 15800 return raw(); |
15718 } | 15801 } |
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 | 15802 // 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 | 15803 // necessarily finalized yet. We may be checking bounds at compile time or |
15728 // finalizing the type argument vector of a recursive type. | 15804 // finalizing the type argument vector of a recursive type. |
15729 const Class& cls = Class::Handle(zone, scope_class()); | 15805 const Class& cls = Class::Handle(zone, scope_class()); |
15730 | 15806 TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments()); |
15807 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); | |
15808 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | |
15809 bound_error, | |
15810 instantiation_trail, | |
15811 bound_trail, | |
15812 space); | |
15731 // This uninstantiated type is not modified, as it can be instantiated | 15813 // This uninstantiated type is not modified, as it can be instantiated |
15732 // with different instantiators. Allocate a new instantiated version of it. | 15814 // with different instantiators. Allocate a new instantiated version of it. |
15733 instantiated_type = | 15815 const FunctionType& instantiated_type = FunctionType::Handle(zone, |
15734 FunctionType::New(cls, | 15816 FunctionType::New(cls, |
15735 TypeArguments::Handle(zone), | 15817 type_arguments, |
15736 Function::Handle(zone, signature()), | 15818 Function::Handle(zone, signature()), |
15737 token_pos(), | 15819 token_pos(), |
15738 space); | 15820 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()) { | 15821 if (IsFinalized()) { |
15750 instantiated_type.SetIsFinalized(); | 15822 instantiated_type.SetIsFinalized(); |
15751 } else { | 15823 } else { |
15752 instantiated_type.SetIsResolved(); | 15824 instantiated_type.SetIsResolved(); |
15753 } | 15825 } |
15754 // Canonicalization is not part of instantiation. | 15826 // Canonicalization is not part of instantiation. |
15755 return instantiated_type.raw(); | 15827 return instantiated_type.raw(); |
15756 } | 15828 } |
15757 | 15829 |
15758 | 15830 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15946 } | 16018 } |
15947 // The type was not found in the table. It is not canonical yet. | 16019 // The type was not found in the table. It is not canonical yet. |
15948 | 16020 |
15949 // Canonicalize the type arguments. | 16021 // Canonicalize the type arguments. |
15950 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 16022 TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
15951 // In case the type is first canonicalized at runtime, its type argument | 16023 // In case the type is first canonicalized at runtime, its type argument |
15952 // vector may be longer than necessary. This is not an issue. | 16024 // vector may be longer than necessary. This is not an issue. |
15953 ASSERT(type_args.IsNull() || | 16025 ASSERT(type_args.IsNull() || |
15954 (type_args.Length() >= scope_cls.NumTypeArguments())); | 16026 (type_args.Length() >= scope_cls.NumTypeArguments())); |
15955 type_args = type_args.Canonicalize(trail); | 16027 type_args = type_args.Canonicalize(trail); |
16028 // Canonicalizing type_args cannot canonicalize this function type as a side | |
16029 // effect, because function types cannot be recursive. Cycles via typedefs | |
16030 // are detected and disallowed. This is in contract to regular types, where | |
rmacnak
2016/02/09 00:50:22
contrast
Shouldn't this be ASSERT(!IsCanonical())
regis
2016/02/09 17:17:38
Good catch! The comment on lines 16028-16031 is ou
| |
16031 // the test is necessary. See Type::Canonicalize. | |
16032 if (IsCanonical()) { | |
16033 // Canonicalizing type_args canonicalized this type as a side effect. | |
16034 ASSERT(IsRecursive()); | |
16035 // Cycles via typedefs are detected and disallowed, but a function type can | |
16036 // be recursive due to a cycle in its type arguments. | |
16037 ASSERT(IsOld()); | |
16038 return this->raw(); | |
16039 } | |
15956 set_arguments(type_args); | 16040 set_arguments(type_args); |
15957 | 16041 |
15958 // Replace the actual function by a signature function. | 16042 // Replace the actual function by a signature function. |
15959 const Function& fun = Function::Handle(zone, signature()); | 16043 const Function& fun = Function::Handle(zone, signature()); |
15960 if (!fun.IsSignatureFunction()) { | 16044 if (!fun.IsSignatureFunction()) { |
15961 Function& sig_fun = Function::Handle(zone, | 16045 Function& sig_fun = Function::Handle(zone, |
15962 Function::NewSignatureFunction(scope_cls, TokenPosition::kNoSource)); | 16046 Function::NewSignatureFunction(scope_cls, TokenPosition::kNoSource)); |
15963 type = fun.result_type(); | 16047 type = fun.result_type(); |
15964 type = type.Canonicalize(trail); | 16048 type = type.Canonicalize(trail); |
15965 sig_fun.set_result_type(type); | 16049 sig_fun.set_result_type(type); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16043 } | 16127 } |
16044 | 16128 |
16045 | 16129 |
16046 void FunctionType::set_scope_class(const Class& value) const { | 16130 void FunctionType::set_scope_class(const Class& value) const { |
16047 ASSERT(!value.IsNull()); | 16131 ASSERT(!value.IsNull()); |
16048 StorePointer(&raw_ptr()->scope_class_, value.raw()); | 16132 StorePointer(&raw_ptr()->scope_class_, value.raw()); |
16049 } | 16133 } |
16050 | 16134 |
16051 | 16135 |
16052 void FunctionType::set_arguments(const TypeArguments& value) const { | 16136 void FunctionType::set_arguments(const TypeArguments& value) const { |
16137 ASSERT(!IsCanonical()); | |
16053 StorePointer(&raw_ptr()->arguments_, value.raw()); | 16138 StorePointer(&raw_ptr()->arguments_, value.raw()); |
16054 } | 16139 } |
16055 | 16140 |
16056 | 16141 |
16057 void FunctionType::set_signature(const Function& value) const { | 16142 void FunctionType::set_signature(const Function& value) const { |
16058 StorePointer(&raw_ptr()->signature_, value.raw()); | 16143 StorePointer(&raw_ptr()->signature_, value.raw()); |
16059 } | 16144 } |
16060 | 16145 |
16061 | 16146 |
16062 RawFunctionType* FunctionType::New(Heap::Space space) { | 16147 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))) { | 16228 if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { |
16144 return true; | 16229 return true; |
16145 } | 16230 } |
16146 return AbstractType::Handle(type()).IsEquivalent(other, trail); | 16231 return AbstractType::Handle(type()).IsEquivalent(other, trail); |
16147 } | 16232 } |
16148 | 16233 |
16149 | 16234 |
16150 RawTypeRef* TypeRef::InstantiateFrom( | 16235 RawTypeRef* TypeRef::InstantiateFrom( |
16151 const TypeArguments& instantiator_type_arguments, | 16236 const TypeArguments& instantiator_type_arguments, |
16152 Error* bound_error, | 16237 Error* bound_error, |
16153 TrailPtr trail, | 16238 TrailPtr instantiation_trail, |
16239 TrailPtr bound_trail, | |
16154 Heap::Space space) const { | 16240 Heap::Space space) const { |
16155 TypeRef& instantiated_type_ref = TypeRef::Handle(); | 16241 TypeRef& instantiated_type_ref = TypeRef::Handle(); |
16156 instantiated_type_ref ^= OnlyBuddyInTrail(trail); | 16242 instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail); |
16157 if (!instantiated_type_ref.IsNull()) { | 16243 if (!instantiated_type_ref.IsNull()) { |
16158 return instantiated_type_ref.raw(); | 16244 return instantiated_type_ref.raw(); |
16159 } | 16245 } |
16246 instantiated_type_ref = TypeRef::New(); | |
16247 AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref); | |
16248 | |
16160 AbstractType& ref_type = AbstractType::Handle(type()); | 16249 AbstractType& ref_type = AbstractType::Handle(type()); |
16161 ASSERT(!ref_type.IsTypeRef()); | 16250 ASSERT(!ref_type.IsTypeRef()); |
16162 AbstractType& instantiated_ref_type = AbstractType::Handle(); | 16251 AbstractType& instantiated_ref_type = AbstractType::Handle(); |
16163 instantiated_ref_type = ref_type.InstantiateFrom( | 16252 instantiated_ref_type = ref_type.InstantiateFrom( |
16164 instantiator_type_arguments, bound_error, trail, space); | 16253 instantiator_type_arguments, |
16254 bound_error, | |
16255 instantiation_trail, | |
16256 bound_trail, | |
16257 space); | |
16165 ASSERT(!instantiated_ref_type.IsTypeRef()); | 16258 ASSERT(!instantiated_ref_type.IsTypeRef()); |
16166 instantiated_type_ref = TypeRef::New(instantiated_ref_type); | 16259 instantiated_type_ref.set_type(instantiated_ref_type); |
16167 AddOnlyBuddyToTrail(&trail, instantiated_type_ref); | |
16168 return instantiated_type_ref.raw(); | 16260 return instantiated_type_ref.raw(); |
16169 } | 16261 } |
16170 | 16262 |
16171 | 16263 |
16172 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, | 16264 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, |
16173 TrailPtr trail) const { | 16265 TrailPtr trail) const { |
16174 TypeRef& cloned_type_ref = TypeRef::Handle(); | 16266 TypeRef& cloned_type_ref = TypeRef::Handle(); |
16175 cloned_type_ref ^= OnlyBuddyInTrail(trail); | 16267 cloned_type_ref ^= OnlyBuddyInTrail(trail); |
16176 if (!cloned_type_ref.IsNull()) { | 16268 if (!cloned_type_ref.IsNull()) { |
16177 return cloned_type_ref.raw(); | 16269 return cloned_type_ref.raw(); |
16178 } | 16270 } |
16271 cloned_type_ref = TypeRef::New(); | |
16272 AddOnlyBuddyToTrail(&trail, cloned_type_ref); | |
16179 AbstractType& ref_type = AbstractType::Handle(type()); | 16273 AbstractType& ref_type = AbstractType::Handle(type()); |
16180 ASSERT(!ref_type.IsTypeRef()); | 16274 ASSERT(!ref_type.IsTypeRef()); |
16181 AbstractType& cloned_ref_type = AbstractType::Handle(); | 16275 AbstractType& cloned_ref_type = AbstractType::Handle(); |
16182 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); | 16276 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); |
16183 ASSERT(!cloned_ref_type.IsTypeRef()); | 16277 ASSERT(!cloned_ref_type.IsTypeRef()); |
16184 cloned_type_ref = TypeRef::New(cloned_ref_type); | 16278 cloned_type_ref.set_type(cloned_ref_type); |
16185 AddOnlyBuddyToTrail(&trail, cloned_type_ref); | |
16186 return cloned_type_ref.raw(); | 16279 return cloned_type_ref.raw(); |
16187 } | 16280 } |
16188 | 16281 |
16189 | 16282 |
16190 void TypeRef::set_type(const AbstractType& value) const { | 16283 void TypeRef::set_type(const AbstractType& value) const { |
16191 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); | 16284 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); |
16192 ASSERT(!value.IsTypeRef()); | 16285 ASSERT(!value.IsTypeRef()); |
16193 StorePointer(&raw_ptr()->type_, value.raw()); | 16286 StorePointer(&raw_ptr()->type_, value.raw()); |
16194 } | 16287 } |
16195 | 16288 |
(...skipping 16 matching lines...) Expand all Loading... | |
16212 | 16305 |
16213 | 16306 |
16214 intptr_t TypeRef::Hash() const { | 16307 intptr_t TypeRef::Hash() const { |
16215 // Do not calculate the hash of the referenced type to avoid divergence. | 16308 // Do not calculate the hash of the referenced type to avoid divergence. |
16216 const uint32_t result = | 16309 const uint32_t result = |
16217 Class::Handle(AbstractType::Handle(type()).type_class()).id(); | 16310 Class::Handle(AbstractType::Handle(type()).type_class()).id(); |
16218 return FinalizeHash(result); | 16311 return FinalizeHash(result); |
16219 } | 16312 } |
16220 | 16313 |
16221 | 16314 |
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() { | 16315 RawTypeRef* TypeRef::New() { |
16259 RawObject* raw = Object::Allocate(TypeRef::kClassId, | 16316 RawObject* raw = Object::Allocate(TypeRef::kClassId, |
16260 TypeRef::InstanceSize(), | 16317 TypeRef::InstanceSize(), |
16261 Heap::kOld); | 16318 Heap::kOld); |
16262 return reinterpret_cast<RawTypeRef*>(raw); | 16319 return reinterpret_cast<RawTypeRef*>(raw); |
16263 } | 16320 } |
16264 | 16321 |
16265 | 16322 |
16266 RawTypeRef* TypeRef::New(const AbstractType& type) { | 16323 RawTypeRef* TypeRef::New(const AbstractType& type) { |
16267 const TypeRef& result = TypeRef::Handle(TypeRef::New()); | 16324 const TypeRef& result = TypeRef::Handle(TypeRef::New()); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16336 | 16393 |
16337 | 16394 |
16338 void TypeParameter::set_bound(const AbstractType& value) const { | 16395 void TypeParameter::set_bound(const AbstractType& value) const { |
16339 StorePointer(&raw_ptr()->bound_, value.raw()); | 16396 StorePointer(&raw_ptr()->bound_, value.raw()); |
16340 } | 16397 } |
16341 | 16398 |
16342 | 16399 |
16343 RawAbstractType* TypeParameter::InstantiateFrom( | 16400 RawAbstractType* TypeParameter::InstantiateFrom( |
16344 const TypeArguments& instantiator_type_arguments, | 16401 const TypeArguments& instantiator_type_arguments, |
16345 Error* bound_error, | 16402 Error* bound_error, |
16346 TrailPtr trail, | 16403 TrailPtr instantiation_trail, |
16404 TrailPtr bound_trail, | |
16347 Heap::Space space) const { | 16405 Heap::Space space) const { |
16348 ASSERT(IsFinalized()); | 16406 ASSERT(IsFinalized()); |
16349 if (instantiator_type_arguments.IsNull()) { | 16407 if (instantiator_type_arguments.IsNull()) { |
16350 return Type::DynamicType(); | 16408 return Type::DynamicType(); |
16351 } | 16409 } |
16352 const AbstractType& type_arg = AbstractType::Handle( | 16410 const AbstractType& type_arg = AbstractType::Handle( |
16353 instantiator_type_arguments.TypeAt(index())); | 16411 instantiator_type_arguments.TypeAt(index())); |
16354 // There is no need to canonicalize the instantiated type parameter, since all | 16412 // 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 | 16413 // type arguments are canonicalized at type finalization time. It would be too |
16356 // early to canonicalize the returned type argument here, since instantiation | 16414 // early to canonicalize the returned type argument here, since instantiation |
16357 // not only happens at run time, but also during type finalization. | 16415 // not only happens at run time, but also during type finalization. |
16416 | |
16417 // If the instantiated type parameter type_arg is a BoundedType, it means that | |
16418 // it is still uninstantiated and that we are instantiating at finalization | |
16419 // time (i.e. compile time). | |
16420 // Indeed, the instantiator (type arguments of an instance) is always | |
16421 // instantiated at run time and any bounds were checked during allocation. | |
16358 return type_arg.raw(); | 16422 return type_arg.raw(); |
16359 } | 16423 } |
16360 | 16424 |
16361 | 16425 |
16362 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 16426 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
16363 const AbstractType& upper_bound, | 16427 const AbstractType& upper_bound, |
16364 Error* bound_error, | 16428 Error* bound_error, |
16429 TrailPtr bound_trail, | |
16365 Heap::Space space) const { | 16430 Heap::Space space) const { |
16366 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 16431 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
16367 ASSERT(bounded_type.IsFinalized()); | 16432 ASSERT(bounded_type.IsFinalized()); |
16368 ASSERT(upper_bound.IsFinalized()); | 16433 ASSERT(upper_bound.IsFinalized()); |
16369 ASSERT(!bounded_type.IsMalformed()); | 16434 ASSERT(!bounded_type.IsMalformed()); |
16370 if (bounded_type.IsSubtypeOf(upper_bound, bound_error, space)) { | 16435 if (bounded_type.IsTypeRef() || upper_bound.IsTypeRef()) { |
16436 // Shortcut the bound check if the pair <bounded_type, upper_bound> is | |
16437 // already in the trail. | |
16438 if (bounded_type.TestAndAddBuddyToTrail(&bound_trail, upper_bound)) { | |
16439 return true; | |
16440 } | |
16441 } | |
16442 | |
16443 if (bounded_type.IsSubtypeOf(upper_bound, bound_error, bound_trail, space)) { | |
16371 return true; | 16444 return true; |
16372 } | 16445 } |
16373 // Set bound_error if the caller is interested and if this is the first error. | 16446 // Set bound_error if the caller is interested and if this is the first error. |
16374 if ((bound_error != NULL) && bound_error->IsNull()) { | 16447 if ((bound_error != NULL) && bound_error->IsNull()) { |
16375 // Report the bound error only if both the bounded type and the upper bound | 16448 // 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. | 16449 // are instantiated. Otherwise, we cannot tell yet it is a bound error. |
16377 if (bounded_type.IsInstantiated() && upper_bound.IsInstantiated()) { | 16450 if (bounded_type.IsInstantiated() && upper_bound.IsInstantiated()) { |
16378 const String& bounded_type_name = String::Handle( | 16451 const String& bounded_type_name = String::Handle( |
16379 bounded_type.UserVisibleName()); | 16452 bounded_type.UserVisibleName()); |
16380 const String& upper_bound_name = String::Handle( | 16453 const String& upper_bound_name = String::Handle( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16417 index(), | 16490 index(), |
16418 String::Handle(name()), | 16491 String::Handle(name()), |
16419 AbstractType::Handle(bound()), | 16492 AbstractType::Handle(bound()), |
16420 token_pos()); | 16493 token_pos()); |
16421 } | 16494 } |
16422 | 16495 |
16423 | 16496 |
16424 RawAbstractType* TypeParameter::CloneUninstantiated( | 16497 RawAbstractType* TypeParameter::CloneUninstantiated( |
16425 const Class& new_owner, TrailPtr trail) const { | 16498 const Class& new_owner, TrailPtr trail) const { |
16426 ASSERT(IsFinalized()); | 16499 ASSERT(IsFinalized()); |
16427 AbstractType& upper_bound = AbstractType::Handle(bound()); | 16500 TypeParameter& clone = TypeParameter::Handle(); |
16428 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | 16501 clone ^= OnlyBuddyInTrail(trail); |
16502 if (!clone.IsNull()) { | |
16503 return clone.raw(); | |
16504 } | |
16429 const Class& old_owner = Class::Handle(parameterized_class()); | 16505 const Class& old_owner = Class::Handle(parameterized_class()); |
16430 const intptr_t new_index = index() + | 16506 const intptr_t new_index = index() + |
16431 new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); | 16507 new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); |
16432 const TypeParameter& clone = TypeParameter::Handle( | 16508 AbstractType& upper_bound = AbstractType::Handle(bound()); |
16433 TypeParameter::New(new_owner, | 16509 clone = TypeParameter::New(new_owner, |
16434 new_index, | 16510 new_index, |
16435 String::Handle(name()), | 16511 String::Handle(name()), |
16436 upper_bound, | 16512 upper_bound, // Not cloned yet. |
16437 token_pos())); | 16513 token_pos()); |
16438 clone.SetIsFinalized(); | 16514 clone.SetIsFinalized(); |
16515 AddOnlyBuddyToTrail(&trail, clone); | |
16516 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | |
16517 clone.set_bound(upper_bound); | |
16439 return clone.raw(); | 16518 return clone.raw(); |
16440 } | 16519 } |
16441 | 16520 |
16442 | 16521 |
16443 intptr_t TypeParameter::Hash() const { | 16522 intptr_t TypeParameter::Hash() const { |
16444 ASSERT(IsFinalized()); | 16523 ASSERT(IsFinalized()); |
16445 uint32_t result = Class::Handle(parameterized_class()).id(); | 16524 uint32_t result = Class::Handle(parameterized_class()).id(); |
16446 // No need to include the hash of the bound, since the type parameter is fully | 16525 // No need to include the hash of the bound, since the type parameter is fully |
16447 // identified by its class and index. | 16526 // identified by its class and index. |
16448 result = CombineHashes(result, index()); | 16527 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 | 16662 // A null type parameter is set when marking a type malformed because of a |
16584 // bound error at compile time. | 16663 // bound error at compile time. |
16585 ASSERT(value.IsNull() || value.IsFinalized()); | 16664 ASSERT(value.IsNull() || value.IsFinalized()); |
16586 StorePointer(&raw_ptr()->type_parameter_, value.raw()); | 16665 StorePointer(&raw_ptr()->type_parameter_, value.raw()); |
16587 } | 16666 } |
16588 | 16667 |
16589 | 16668 |
16590 RawAbstractType* BoundedType::InstantiateFrom( | 16669 RawAbstractType* BoundedType::InstantiateFrom( |
16591 const TypeArguments& instantiator_type_arguments, | 16670 const TypeArguments& instantiator_type_arguments, |
16592 Error* bound_error, | 16671 Error* bound_error, |
16593 TrailPtr trail, | 16672 TrailPtr instantiation_trail, |
16673 TrailPtr bound_trail, | |
16594 Heap::Space space) const { | 16674 Heap::Space space) const { |
16595 ASSERT(IsFinalized()); | 16675 ASSERT(IsFinalized()); |
16596 AbstractType& bounded_type = AbstractType::Handle(type()); | 16676 AbstractType& bounded_type = AbstractType::Handle(type()); |
16597 ASSERT(bounded_type.IsFinalized()); | 16677 ASSERT(bounded_type.IsFinalized()); |
16678 AbstractType& instantiated_bounded_type = | |
16679 AbstractType::Handle(bounded_type.raw()); | |
16598 if (!bounded_type.IsInstantiated()) { | 16680 if (!bounded_type.IsInstantiated()) { |
16599 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, | 16681 instantiated_bounded_type = |
16600 bound_error, | 16682 bounded_type.InstantiateFrom(instantiator_type_arguments, |
16601 trail, | 16683 bound_error, |
16602 space); | 16684 instantiation_trail, |
16603 // In case types of instantiator_type_arguments are not finalized, then | 16685 bound_trail, |
16604 // the instantiated bounded_type is not finalized either. | 16686 space); |
16687 // In case types of instantiator_type_arguments are not finalized | |
16688 // (or instantiated), then the instantiated_bounded_type is not finalized | |
16689 // (or instantiated) either. | |
16605 // Note that instantiator_type_arguments must have the final length, though. | 16690 // Note that instantiator_type_arguments must have the final length, though. |
16606 } | 16691 } |
16607 if ((Isolate::Current()->flags().type_checks()) && | 16692 if ((Isolate::Current()->flags().type_checks()) && |
16608 (bound_error != NULL) && bound_error->IsNull()) { | 16693 (bound_error != NULL) && bound_error->IsNull()) { |
16609 AbstractType& upper_bound = AbstractType::Handle(bound()); | 16694 AbstractType& upper_bound = AbstractType::Handle(bound()); |
16610 ASSERT(upper_bound.IsFinalized()); | 16695 ASSERT(upper_bound.IsFinalized()); |
16611 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); | 16696 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); |
16612 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 16697 AbstractType& instantiated_upper_bound = |
16698 AbstractType::Handle(upper_bound.raw()); | |
16613 if (!upper_bound.IsInstantiated()) { | 16699 if (!upper_bound.IsInstantiated()) { |
16614 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, | 16700 instantiated_upper_bound = |
16615 bound_error, | 16701 upper_bound.InstantiateFrom(instantiator_type_arguments, |
16616 trail, | 16702 bound_error, |
16617 space); | 16703 instantiation_trail, |
16618 // Instantiated upper_bound may not be finalized. See comment above. | 16704 bound_trail, |
16705 space); | |
16706 // The instantiated_upper_bound may not be finalized or instantiated. | |
16707 // See comment above. | |
16619 } | 16708 } |
16620 if (bound_error->IsNull()) { | 16709 if (bound_error->IsNull()) { |
16621 if (bounded_type.IsBeingFinalized() || | 16710 // Shortcut the F-bounded case where we have reached a fixpoint. |
16622 upper_bound.IsBeingFinalized() || | 16711 if (instantiated_bounded_type.Equals(bounded_type) && |
16623 (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && | 16712 instantiated_upper_bound.Equals(upper_bound)) { |
16713 return bounded_type.raw(); | |
16714 } | |
16715 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | |
16716 if (instantiated_bounded_type.IsBeingFinalized() || | |
16717 instantiated_upper_bound.IsBeingFinalized() || | |
16718 (!type_param.CheckBound(instantiated_bounded_type, | |
16719 instantiated_upper_bound, | |
16720 bound_error, | |
16721 bound_trail) && | |
16624 bound_error->IsNull())) { | 16722 bound_error->IsNull())) { |
16625 // We cannot determine yet whether the bounded_type is below the | 16723 // 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 | 16724 // upper_bound, because one or both of them is still being finalized or |
16627 // uninstantiated. | 16725 // uninstantiated. |
16628 ASSERT(bounded_type.IsBeingFinalized() || | 16726 ASSERT(instantiated_bounded_type.IsBeingFinalized() || |
16629 upper_bound.IsBeingFinalized() || | 16727 instantiated_upper_bound.IsBeingFinalized() || |
16630 !bounded_type.IsInstantiated() || | 16728 !instantiated_bounded_type.IsInstantiated() || |
16631 !upper_bound.IsInstantiated()); | 16729 !instantiated_upper_bound.IsInstantiated()); |
16632 // Postpone bound check by returning a new BoundedType with unfinalized | 16730 // Postpone bound check by returning a new BoundedType with unfinalized |
16633 // or partially instantiated bounded_type and upper_bound, but keeping | 16731 // or partially instantiated bounded_type and upper_bound, but keeping |
16634 // type_param. | 16732 // type_param. |
16635 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); | 16733 instantiated_bounded_type = BoundedType::New(instantiated_bounded_type, |
16734 instantiated_upper_bound, | |
16735 type_param); | |
16636 } | 16736 } |
16637 } | 16737 } |
16638 } | 16738 } |
16639 return bounded_type.raw(); | 16739 return instantiated_bounded_type.raw(); |
16640 } | 16740 } |
16641 | 16741 |
16642 | 16742 |
16643 RawAbstractType* BoundedType::CloneUnfinalized() const { | 16743 RawAbstractType* BoundedType::CloneUnfinalized() const { |
16644 if (IsFinalized()) { | 16744 if (IsFinalized()) { |
16645 return raw(); | 16745 return raw(); |
16646 } | 16746 } |
16647 AbstractType& bounded_type = AbstractType::Handle(type()); | 16747 AbstractType& bounded_type = AbstractType::Handle(type()); |
16648 | 16748 |
16649 bounded_type = bounded_type.CloneUnfinalized(); | 16749 bounded_type = bounded_type.CloneUnfinalized(); |
(...skipping 4726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
21376 return UserTag::null(); | 21476 return UserTag::null(); |
21377 } | 21477 } |
21378 | 21478 |
21379 | 21479 |
21380 const char* UserTag::ToCString() const { | 21480 const char* UserTag::ToCString() const { |
21381 const String& tag_label = String::Handle(label()); | 21481 const String& tag_label = String::Handle(label()); |
21382 return tag_label.ToCString(); | 21482 return tag_label.ToCString(); |
21383 } | 21483 } |
21384 | 21484 |
21385 } // namespace dart | 21485 } // namespace dart |
OLD | NEW |