Chromium Code Reviews| 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 |