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

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: address comments 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 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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