Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: runtime/vm/object.cc

Issue 1674383002: Keep a trail while checking upper bounds in the VM in order to properly handle (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698