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