OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/become.h" | 10 #include "vm/become.h" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 // they are being used. | 104 // they are being used. |
105 #if defined(RAW_NULL) | 105 #if defined(RAW_NULL) |
106 #error RAW_NULL should not be defined. | 106 #error RAW_NULL should not be defined. |
107 #endif | 107 #endif |
108 #define RAW_NULL kHeapObjectTag | 108 #define RAW_NULL kHeapObjectTag |
109 Object* Object::null_object_ = NULL; | 109 Object* Object::null_object_ = NULL; |
110 Array* Object::null_array_ = NULL; | 110 Array* Object::null_array_ = NULL; |
111 String* Object::null_string_ = NULL; | 111 String* Object::null_string_ = NULL; |
112 Instance* Object::null_instance_ = NULL; | 112 Instance* Object::null_instance_ = NULL; |
113 TypeArguments* Object::null_type_arguments_ = NULL; | 113 TypeArguments* Object::null_type_arguments_ = NULL; |
| 114 TypeArguments* Object::empty_type_arguments_ = NULL; |
114 Array* Object::empty_array_ = NULL; | 115 Array* Object::empty_array_ = NULL; |
115 Array* Object::zero_array_ = NULL; | 116 Array* Object::zero_array_ = NULL; |
116 Context* Object::empty_context_ = NULL; | 117 Context* Object::empty_context_ = NULL; |
117 ContextScope* Object::empty_context_scope_ = NULL; | 118 ContextScope* Object::empty_context_scope_ = NULL; |
118 ObjectPool* Object::empty_object_pool_ = NULL; | 119 ObjectPool* Object::empty_object_pool_ = NULL; |
119 PcDescriptors* Object::empty_descriptors_ = NULL; | 120 PcDescriptors* Object::empty_descriptors_ = NULL; |
120 LocalVarDescriptors* Object::empty_var_descriptors_ = NULL; | 121 LocalVarDescriptors* Object::empty_var_descriptors_ = NULL; |
121 ExceptionHandlers* Object::empty_exception_handlers_ = NULL; | 122 ExceptionHandlers* Object::empty_exception_handlers_ = NULL; |
122 Array* Object::extractor_parameter_types_ = NULL; | 123 Array* Object::extractor_parameter_types_ = NULL; |
123 Array* Object::extractor_parameter_names_ = NULL; | 124 Array* Object::extractor_parameter_names_ = NULL; |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 } | 509 } |
509 | 510 |
510 Heap* heap = isolate->heap(); | 511 Heap* heap = isolate->heap(); |
511 | 512 |
512 // Allocate the read only object handles here. | 513 // Allocate the read only object handles here. |
513 null_object_ = Object::ReadOnlyHandle(); | 514 null_object_ = Object::ReadOnlyHandle(); |
514 null_array_ = Array::ReadOnlyHandle(); | 515 null_array_ = Array::ReadOnlyHandle(); |
515 null_string_ = String::ReadOnlyHandle(); | 516 null_string_ = String::ReadOnlyHandle(); |
516 null_instance_ = Instance::ReadOnlyHandle(); | 517 null_instance_ = Instance::ReadOnlyHandle(); |
517 null_type_arguments_ = TypeArguments::ReadOnlyHandle(); | 518 null_type_arguments_ = TypeArguments::ReadOnlyHandle(); |
| 519 empty_type_arguments_ = TypeArguments::ReadOnlyHandle(); |
518 empty_array_ = Array::ReadOnlyHandle(); | 520 empty_array_ = Array::ReadOnlyHandle(); |
519 zero_array_ = Array::ReadOnlyHandle(); | 521 zero_array_ = Array::ReadOnlyHandle(); |
520 empty_context_ = Context::ReadOnlyHandle(); | 522 empty_context_ = Context::ReadOnlyHandle(); |
521 empty_context_scope_ = ContextScope::ReadOnlyHandle(); | 523 empty_context_scope_ = ContextScope::ReadOnlyHandle(); |
522 empty_object_pool_ = ObjectPool::ReadOnlyHandle(); | 524 empty_object_pool_ = ObjectPool::ReadOnlyHandle(); |
523 empty_descriptors_ = PcDescriptors::ReadOnlyHandle(); | 525 empty_descriptors_ = PcDescriptors::ReadOnlyHandle(); |
524 empty_var_descriptors_ = LocalVarDescriptors::ReadOnlyHandle(); | 526 empty_var_descriptors_ = LocalVarDescriptors::ReadOnlyHandle(); |
525 empty_exception_handlers_ = ExceptionHandlers::ReadOnlyHandle(); | 527 empty_exception_handlers_ = ExceptionHandlers::ReadOnlyHandle(); |
526 extractor_parameter_types_ = Array::ReadOnlyHandle(); | 528 extractor_parameter_types_ = Array::ReadOnlyHandle(); |
527 extractor_parameter_names_ = Array::ReadOnlyHandle(); | 529 extractor_parameter_names_ = Array::ReadOnlyHandle(); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 isolate->object_store()->set_double_class(cls); | 751 isolate->object_store()->set_double_class(cls); |
750 | 752 |
751 // Ensure that class kExternalTypedDataUint8ArrayCid is registered as we | 753 // Ensure that class kExternalTypedDataUint8ArrayCid is registered as we |
752 // need it when reading in the token stream of bootstrap classes in the VM | 754 // need it when reading in the token stream of bootstrap classes in the VM |
753 // isolate. | 755 // isolate. |
754 Class::NewExternalTypedDataClass(kExternalTypedDataUint8ArrayCid); | 756 Class::NewExternalTypedDataClass(kExternalTypedDataUint8ArrayCid); |
755 | 757 |
756 // Needed for object pools of VM isolate stubs. | 758 // Needed for object pools of VM isolate stubs. |
757 Class::NewTypedDataClass(kTypedDataInt8ArrayCid); | 759 Class::NewTypedDataClass(kTypedDataInt8ArrayCid); |
758 | 760 |
| 761 // Allocate and initialize the empty_type_arguments instance. |
| 762 { |
| 763 uword address = heap->Allocate(TypeArguments::InstanceSize(0), Heap::kOld); |
| 764 InitializeObject(address, TypeArguments::kClassId, |
| 765 TypeArguments::InstanceSize(0), true); |
| 766 TypeArguments::initializeHandle( |
| 767 empty_type_arguments_, |
| 768 reinterpret_cast<RawTypeArguments*>(address + kHeapObjectTag)); |
| 769 empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->length_, |
| 770 Smi::New(0)); |
| 771 empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->hash_, |
| 772 Smi::New(0)); |
| 773 // instantiations_ field is initialized to null and should not be used. |
| 774 empty_type_arguments_->SetCanonical(); |
| 775 } |
| 776 |
759 // Allocate and initialize the empty_array instance. | 777 // Allocate and initialize the empty_array instance. |
760 { | 778 { |
761 uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld); | 779 uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld); |
762 InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0), true); | 780 InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0), true); |
763 Array::initializeHandle( | 781 Array::initializeHandle( |
764 empty_array_, reinterpret_cast<RawArray*>(address + kHeapObjectTag)); | 782 empty_array_, reinterpret_cast<RawArray*>(address + kHeapObjectTag)); |
765 empty_array_->StoreSmi(&empty_array_->raw_ptr()->length_, Smi::New(0)); | 783 empty_array_->StoreSmi(&empty_array_->raw_ptr()->length_, Smi::New(0)); |
766 empty_array_->SetCanonical(); | 784 empty_array_->SetCanonical(); |
767 } | 785 } |
768 | 786 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 | 942 |
925 ASSERT(!null_object_->IsSmi()); | 943 ASSERT(!null_object_->IsSmi()); |
926 ASSERT(!null_array_->IsSmi()); | 944 ASSERT(!null_array_->IsSmi()); |
927 ASSERT(null_array_->IsArray()); | 945 ASSERT(null_array_->IsArray()); |
928 ASSERT(!null_string_->IsSmi()); | 946 ASSERT(!null_string_->IsSmi()); |
929 ASSERT(null_string_->IsString()); | 947 ASSERT(null_string_->IsString()); |
930 ASSERT(!null_instance_->IsSmi()); | 948 ASSERT(!null_instance_->IsSmi()); |
931 ASSERT(null_instance_->IsInstance()); | 949 ASSERT(null_instance_->IsInstance()); |
932 ASSERT(!null_type_arguments_->IsSmi()); | 950 ASSERT(!null_type_arguments_->IsSmi()); |
933 ASSERT(null_type_arguments_->IsTypeArguments()); | 951 ASSERT(null_type_arguments_->IsTypeArguments()); |
| 952 ASSERT(!empty_type_arguments_->IsSmi()); |
| 953 ASSERT(empty_type_arguments_->IsTypeArguments()); |
934 ASSERT(!empty_array_->IsSmi()); | 954 ASSERT(!empty_array_->IsSmi()); |
935 ASSERT(empty_array_->IsArray()); | 955 ASSERT(empty_array_->IsArray()); |
936 ASSERT(!zero_array_->IsSmi()); | 956 ASSERT(!zero_array_->IsSmi()); |
937 ASSERT(zero_array_->IsArray()); | 957 ASSERT(zero_array_->IsArray()); |
938 ASSERT(!empty_context_->IsSmi()); | 958 ASSERT(!empty_context_->IsSmi()); |
939 ASSERT(empty_context_->IsContext()); | 959 ASSERT(empty_context_->IsContext()); |
940 ASSERT(!empty_context_scope_->IsSmi()); | 960 ASSERT(!empty_context_scope_->IsSmi()); |
941 ASSERT(empty_context_scope_->IsContextScope()); | 961 ASSERT(empty_context_scope_->IsContextScope()); |
942 ASSERT(!empty_descriptors_->IsSmi()); | 962 ASSERT(!empty_descriptors_->IsSmi()); |
943 ASSERT(empty_descriptors_->IsPcDescriptors()); | 963 ASSERT(empty_descriptors_->IsPcDescriptors()); |
(...skipping 3766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4710 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, | 4730 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, |
4711 intptr_t from_index, | 4731 intptr_t from_index, |
4712 intptr_t len) const { | 4732 intptr_t len) const { |
4713 ASSERT(Length() >= (from_index + len)); | 4733 ASSERT(Length() >= (from_index + len)); |
4714 AbstractType& type = AbstractType::Handle(); | 4734 AbstractType& type = AbstractType::Handle(); |
4715 Class& type_class = Class::Handle(); | 4735 Class& type_class = Class::Handle(); |
4716 for (intptr_t i = 0; i < len; i++) { | 4736 for (intptr_t i = 0; i < len; i++) { |
4717 type = TypeAt(from_index + i); | 4737 type = TypeAt(from_index + i); |
4718 if (!type.HasResolvedTypeClass()) { | 4738 if (!type.HasResolvedTypeClass()) { |
4719 if (raw_instantiated && type.IsTypeParameter()) { | 4739 if (raw_instantiated && type.IsTypeParameter()) { |
4720 const TypeParameter& type_param = TypeParameter::Cast(type); | 4740 // An uninstantiated type parameter is equivalent to dynamic (even in |
4721 if (type_param.IsClassTypeParameter() || | 4741 // the presence of a malformed bound in checked mode). |
4722 (type_param.IsFunctionTypeParameter() && | 4742 continue; |
4723 type_param.parent_level() == 0)) { | |
4724 // An uninstantiated type parameter is equivalent to dynamic (even in | |
4725 // the presence of a malformed bound in checked mode). | |
4726 continue; | |
4727 } | |
4728 } | 4743 } |
4729 return false; | 4744 return false; |
4730 } | 4745 } |
4731 type_class = type.type_class(); | 4746 type_class = type.type_class(); |
4732 if (!type_class.IsDynamicClass()) { | 4747 if (!type_class.IsDynamicClass()) { |
4733 return false; | 4748 return false; |
4734 } | 4749 } |
4735 } | 4750 } |
4736 return true; | 4751 return true; |
4737 } | 4752 } |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5021 } | 5036 } |
5022 | 5037 |
5023 | 5038 |
5024 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( | 5039 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( |
5025 const TypeArguments& instantiator_type_arguments, | 5040 const TypeArguments& instantiator_type_arguments, |
5026 const TypeArguments& function_type_arguments, | 5041 const TypeArguments& function_type_arguments, |
5027 Error* bound_error) const { | 5042 Error* bound_error) const { |
5028 ASSERT(!IsInstantiated()); | 5043 ASSERT(!IsInstantiated()); |
5029 ASSERT(instantiator_type_arguments.IsNull() || | 5044 ASSERT(instantiator_type_arguments.IsNull() || |
5030 instantiator_type_arguments.IsCanonical()); | 5045 instantiator_type_arguments.IsCanonical()); |
| 5046 // TODO(regis): It is not clear yet whether we will canonicalize the result |
| 5047 // of the concatenation of function_type_arguments in a nested generic |
| 5048 // function. Leave the assert for now to be safe, but plan on revisiting. |
5031 ASSERT(function_type_arguments.IsNull() || | 5049 ASSERT(function_type_arguments.IsNull() || |
5032 function_type_arguments.IsCanonical()); | 5050 function_type_arguments.IsCanonical()); |
5033 // Lookup instantiator and, if found, return paired instantiated result. | 5051 // Lookup instantiator and, if found, return paired instantiated result. |
5034 Array& prior_instantiations = Array::Handle(instantiations()); | 5052 Array& prior_instantiations = Array::Handle(instantiations()); |
5035 ASSERT(!prior_instantiations.IsNull() && prior_instantiations.IsArray()); | 5053 ASSERT(!prior_instantiations.IsNull() && prior_instantiations.IsArray()); |
5036 // The instantiations cache is initialized with Object::zero_array() and is | 5054 // The instantiations cache is initialized with Object::zero_array() and is |
5037 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 5055 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
5038 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. | 5056 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. |
5039 intptr_t index = 0; | 5057 intptr_t index = 0; |
5040 while (true) { | 5058 while (true) { |
(...skipping 11 matching lines...) Expand all Loading... |
5052 result = InstantiateFrom(instantiator_type_arguments, function_type_arguments, | 5070 result = InstantiateFrom(instantiator_type_arguments, function_type_arguments, |
5053 bound_error, NULL, NULL, Heap::kOld); | 5071 bound_error, NULL, NULL, Heap::kOld); |
5054 if ((bound_error != NULL) && !bound_error->IsNull()) { | 5072 if ((bound_error != NULL) && !bound_error->IsNull()) { |
5055 return result.raw(); | 5073 return result.raw(); |
5056 } | 5074 } |
5057 // Instantiation did not result in bound error. Canonicalize type arguments. | 5075 // Instantiation did not result in bound error. Canonicalize type arguments. |
5058 result = result.Canonicalize(); | 5076 result = result.Canonicalize(); |
5059 // InstantiateAndCanonicalizeFrom is not reentrant. It cannot have been called | 5077 // InstantiateAndCanonicalizeFrom is not reentrant. It cannot have been called |
5060 // indirectly, so the prior_instantiations array cannot have grown. | 5078 // indirectly, so the prior_instantiations array cannot have grown. |
5061 ASSERT(prior_instantiations.raw() == instantiations()); | 5079 ASSERT(prior_instantiations.raw() == instantiations()); |
5062 // Do not cache result if the context is required to instantiate the | |
5063 // type arguments, i.e. they refer to the type parameters of parent functions. | |
5064 if (!IsInstantiated(kParentFunctions)) { | |
5065 return result.raw(); | |
5066 } | |
5067 // Add instantiator and function type args and result to instantiations array. | 5080 // Add instantiator and function type args and result to instantiations array. |
5068 intptr_t length = prior_instantiations.Length(); | 5081 intptr_t length = prior_instantiations.Length(); |
5069 if ((index + StubCode::kInstantiationSizeInWords) >= length) { | 5082 if ((index + StubCode::kInstantiationSizeInWords) >= length) { |
5070 // TODO(regis): Should we limit the number of cached instantiations? | 5083 // TODO(regis): Should we limit the number of cached instantiations? |
5071 // Grow the instantiations array. | 5084 // Grow the instantiations array. |
5072 // The initial array is Object::zero_array() of length 1. | 5085 // The initial array is Object::zero_array() of length 1. |
5073 length = (length > 64) | 5086 length = (length > 64) |
5074 ? (length + 64) | 5087 ? (length + 64) |
5075 : ((length == 1) ? StubCode::kInstantiationSizeInWords + 1 | 5088 : ((length == 1) ? StubCode::kInstantiationSizeInWords + 1 |
5076 : ((length - 1) * 2 + 1)); | 5089 : ((length - 1) * 2 + 1)); |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5982 } | 5995 } |
5983 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 5996 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
5984 TypeArguments& type_params = thread->TypeArgumentsHandle(); | 5997 TypeArguments& type_params = thread->TypeArgumentsHandle(); |
5985 type_params = type_parameters(); | 5998 type_params = type_parameters(); |
5986 // We require null to represent a non-generic function. | 5999 // We require null to represent a non-generic function. |
5987 ASSERT(type_params.Length() != 0); | 6000 ASSERT(type_params.Length() != 0); |
5988 return type_params.Length(); | 6001 return type_params.Length(); |
5989 } | 6002 } |
5990 | 6003 |
5991 | 6004 |
| 6005 intptr_t Function::NumParentTypeParameters() const { |
| 6006 Thread* thread = Thread::Current(); |
| 6007 Function& parent = Function::Handle(parent_function()); |
| 6008 intptr_t num_parent_type_params = 0; |
| 6009 while (!parent.IsNull()) { |
| 6010 num_parent_type_params += parent.NumTypeParameters(thread); |
| 6011 parent ^= parent.parent_function(); |
| 6012 } |
| 6013 return num_parent_type_params; |
| 6014 } |
| 6015 |
| 6016 |
5992 RawTypeParameter* Function::LookupTypeParameter( | 6017 RawTypeParameter* Function::LookupTypeParameter( |
5993 const String& type_name, | 6018 const String& type_name, |
5994 intptr_t* function_level) const { | 6019 intptr_t* function_level) const { |
5995 ASSERT(!type_name.IsNull()); | 6020 ASSERT(!type_name.IsNull()); |
5996 Thread* thread = Thread::Current(); | 6021 Thread* thread = Thread::Current(); |
5997 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 6022 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
5998 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); | 6023 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); |
5999 REUSABLE_STRING_HANDLESCOPE(thread); | 6024 REUSABLE_STRING_HANDLESCOPE(thread); |
6000 REUSABLE_FUNCTION_HANDLESCOPE(thread); | 6025 REUSABLE_FUNCTION_HANDLESCOPE(thread); |
6001 TypeArguments& type_params = thread->TypeArgumentsHandle(); | 6026 TypeArguments& type_params = thread->TypeArgumentsHandle(); |
6002 TypeParameter& type_param = thread->TypeParameterHandle(); | 6027 TypeParameter& type_param = thread->TypeParameterHandle(); |
6003 String& type_param_name = thread->StringHandle(); | 6028 String& type_param_name = thread->StringHandle(); |
6004 Function& function = thread->FunctionHandle(); | 6029 Function& function = thread->FunctionHandle(); |
6005 | 6030 |
6006 function ^= this->raw(); | 6031 function ^= this->raw(); |
6007 intptr_t parent_level = 0; | |
6008 while (!function.IsNull()) { | 6032 while (!function.IsNull()) { |
6009 type_params ^= function.type_parameters(); | 6033 type_params ^= function.type_parameters(); |
6010 if (!type_params.IsNull()) { | 6034 if (!type_params.IsNull()) { |
6011 const intptr_t num_type_params = type_params.Length(); | 6035 const intptr_t num_type_params = type_params.Length(); |
6012 for (intptr_t i = 0; i < num_type_params; i++) { | 6036 for (intptr_t i = 0; i < num_type_params; i++) { |
6013 type_param ^= type_params.TypeAt(i); | 6037 type_param ^= type_params.TypeAt(i); |
6014 type_param_name = type_param.name(); | 6038 type_param_name = type_param.name(); |
6015 if (type_param_name.Equals(type_name)) { | 6039 if (type_param_name.Equals(type_name)) { |
6016 if (parent_level > 0) { | |
6017 // Clone type parameter and set parent_level. | |
6018 type_param = TypeParameter::New( | |
6019 Class::Handle(), function, type_param.index(), parent_level, | |
6020 type_param_name, AbstractType::Handle(type_param.bound()), | |
6021 TokenPosition::kNoSource); | |
6022 type_param.SetIsFinalized(); | |
6023 } | |
6024 return type_param.raw(); | 6040 return type_param.raw(); |
6025 } | 6041 } |
6026 } | 6042 } |
6027 } | 6043 } |
6028 function ^= function.parent_function(); | 6044 function ^= function.parent_function(); |
6029 parent_level++; | |
6030 if (function_level != NULL) { | 6045 if (function_level != NULL) { |
6031 (*function_level)--; | 6046 (*function_level)--; |
6032 } | 6047 } |
6033 } | 6048 } |
6034 return TypeParameter::null(); | 6049 return TypeParameter::null(); |
6035 } | 6050 } |
6036 | 6051 |
6037 | 6052 |
6038 void Function::set_kind(RawFunction::Kind value) const { | 6053 void Function::set_kind(RawFunction::Kind value) const { |
6039 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); | 6054 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6543 const intptr_t num_ignored_params = NumImplicitParameters(); | 6558 const intptr_t num_ignored_params = NumImplicitParameters(); |
6544 const intptr_t other_num_ignored_params = other.NumImplicitParameters(); | 6559 const intptr_t other_num_ignored_params = other.NumImplicitParameters(); |
6545 if (((num_fixed_params - num_ignored_params) > | 6560 if (((num_fixed_params - num_ignored_params) > |
6546 (other_num_fixed_params - other_num_ignored_params)) || | 6561 (other_num_fixed_params - other_num_ignored_params)) || |
6547 ((num_fixed_params - num_ignored_params + num_opt_pos_params) < | 6562 ((num_fixed_params - num_ignored_params + num_opt_pos_params) < |
6548 (other_num_fixed_params - other_num_ignored_params + | 6563 (other_num_fixed_params - other_num_ignored_params + |
6549 other_num_opt_pos_params)) || | 6564 other_num_opt_pos_params)) || |
6550 (num_opt_named_params < other_num_opt_named_params)) { | 6565 (num_opt_named_params < other_num_opt_named_params)) { |
6551 return false; | 6566 return false; |
6552 } | 6567 } |
| 6568 |
| 6569 // TODO(regis): Check the type parameters and bounds of a generic function. |
| 6570 |
6553 // Check the result type. | 6571 // Check the result type. |
6554 const AbstractType& other_res_type = | 6572 const AbstractType& other_res_type = |
6555 AbstractType::Handle(other.result_type()); | 6573 AbstractType::Handle(other.result_type()); |
6556 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { | 6574 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { |
6557 const AbstractType& res_type = AbstractType::Handle(result_type()); | 6575 const AbstractType& res_type = AbstractType::Handle(result_type()); |
6558 if (res_type.IsVoidType()) { | 6576 if (res_type.IsVoidType()) { |
6559 return false; | 6577 return false; |
6560 } | 6578 } |
6561 if (test_kind == kIsSubtypeOf) { | 6579 if (test_kind == kIsSubtypeOf) { |
6562 if (!res_type.IsSubtypeOf(other_res_type, bound_error, NULL, space) && | 6580 if (!res_type.IsSubtypeOf(other_res_type, bound_error, NULL, space) && |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6962 pieces->Add(Symbols::RBrace()); | 6980 pieces->Add(Symbols::RBrace()); |
6963 } | 6981 } |
6964 } | 6982 } |
6965 } | 6983 } |
6966 | 6984 |
6967 | 6985 |
6968 RawInstance* Function::ImplicitStaticClosure() const { | 6986 RawInstance* Function::ImplicitStaticClosure() const { |
6969 if (implicit_static_closure() == Instance::null()) { | 6987 if (implicit_static_closure() == Instance::null()) { |
6970 Zone* zone = Thread::Current()->zone(); | 6988 Zone* zone = Thread::Current()->zone(); |
6971 const Context& context = Object::empty_context(); | 6989 const Context& context = Object::empty_context(); |
6972 const TypeArguments& instantiator = TypeArguments::Handle(zone); | 6990 TypeArguments& function_type_arguments = TypeArguments::Handle(zone); |
6973 Instance& closure = Instance::Handle( | 6991 if (!HasInstantiatedSignature(kFunctions)) { |
6974 zone, Closure::New(instantiator, *this, context, Heap::kOld)); | 6992 function_type_arguments = Object::empty_type_arguments().raw(); |
| 6993 } |
| 6994 Instance& closure = |
| 6995 Instance::Handle(zone, Closure::New(Object::null_type_arguments(), |
| 6996 function_type_arguments, *this, |
| 6997 context, Heap::kOld)); |
6975 set_implicit_static_closure(closure); | 6998 set_implicit_static_closure(closure); |
6976 } | 6999 } |
6977 return implicit_static_closure(); | 7000 return implicit_static_closure(); |
6978 } | 7001 } |
6979 | 7002 |
6980 | 7003 |
6981 RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const { | 7004 RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const { |
6982 ASSERT(IsImplicitClosureFunction()); | 7005 ASSERT(IsImplicitClosureFunction()); |
6983 Zone* zone = Thread::Current()->zone(); | 7006 Zone* zone = Thread::Current()->zone(); |
6984 const Context& context = Context::Handle(zone, Context::New(1)); | 7007 const Context& context = Context::Handle(zone, Context::New(1)); |
6985 context.SetAt(0, receiver); | 7008 context.SetAt(0, receiver); |
6986 TypeArguments& instantiator = TypeArguments::Handle(zone); | 7009 TypeArguments& instantiator_type_arguments = TypeArguments::Handle(zone); |
| 7010 TypeArguments& function_type_arguments = TypeArguments::Handle(zone); |
6987 if (!HasInstantiatedSignature(kCurrentClass)) { | 7011 if (!HasInstantiatedSignature(kCurrentClass)) { |
6988 instantiator = receiver.GetTypeArguments(); | 7012 instantiator_type_arguments = receiver.GetTypeArguments(); |
6989 } | 7013 } |
6990 return Closure::New(instantiator, *this, context); | 7014 if (!HasInstantiatedSignature(kFunctions)) { |
| 7015 function_type_arguments = Object::empty_type_arguments().raw(); |
| 7016 } |
| 7017 return Closure::New(instantiator_type_arguments, function_type_arguments, |
| 7018 *this, context); |
6991 } | 7019 } |
6992 | 7020 |
6993 | 7021 |
6994 RawSmi* Function::GetClosureHashCode() const { | 7022 RawSmi* Function::GetClosureHashCode() const { |
6995 ASSERT(IsClosureFunction()); | 7023 ASSERT(IsClosureFunction()); |
6996 const Object& obj = Object::Handle(raw_ptr()->data_); | 7024 const Object& obj = Object::Handle(raw_ptr()->data_); |
6997 ASSERT(!obj.IsNull()); | 7025 ASSERT(!obj.IsNull()); |
6998 if (ClosureData::Cast(obj).hash() != Object::null()) { | 7026 if (ClosureData::Cast(obj).hash() != Object::null()) { |
6999 return Smi::RawCast(ClosureData::Cast(obj).hash()); | 7027 return Smi::RawCast(ClosureData::Cast(obj).hash()); |
7000 } | 7028 } |
(...skipping 8647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15648 RawAbstractType* Instance::GetType(Heap::Space space) const { | 15676 RawAbstractType* Instance::GetType(Heap::Space space) const { |
15649 if (IsNull()) { | 15677 if (IsNull()) { |
15650 return Type::NullType(); | 15678 return Type::NullType(); |
15651 } | 15679 } |
15652 const Class& cls = Class::Handle(clazz()); | 15680 const Class& cls = Class::Handle(clazz()); |
15653 if (cls.IsClosureClass()) { | 15681 if (cls.IsClosureClass()) { |
15654 const Function& signature = | 15682 const Function& signature = |
15655 Function::Handle(Closure::Cast(*this).function()); | 15683 Function::Handle(Closure::Cast(*this).function()); |
15656 Type& type = Type::Handle(signature.SignatureType()); | 15684 Type& type = Type::Handle(signature.SignatureType()); |
15657 if (!type.IsInstantiated()) { | 15685 if (!type.IsInstantiated()) { |
15658 TypeArguments& instantiator_type_arguments = | 15686 const TypeArguments& instantiator_type_arguments = TypeArguments::Handle( |
15659 TypeArguments::Handle(Closure::Cast(*this).instantiator()); | 15687 Closure::Cast(*this).instantiator_type_arguments()); |
15660 const TypeArguments& function_type_arguments = | 15688 const TypeArguments& function_type_arguments = |
15661 TypeArguments::Handle(signature.type_parameters()); | 15689 TypeArguments::Handle(Closure::Cast(*this).function_type_arguments()); |
15662 // TODO(regis): Pass the closure context to InstantiateSignatureFrom(). | |
15663 // No bound error possible, since the instance exists. | 15690 // No bound error possible, since the instance exists. |
15664 type ^= type.InstantiateFrom(instantiator_type_arguments, | 15691 type ^= type.InstantiateFrom(instantiator_type_arguments, |
15665 function_type_arguments, NULL, NULL, NULL, | 15692 function_type_arguments, NULL, NULL, NULL, |
15666 space); | 15693 space); |
15667 } | 15694 } |
15668 type ^= type.Canonicalize(); | 15695 type ^= type.Canonicalize(); |
15669 return type.raw(); | 15696 return type.raw(); |
15670 } | 15697 } |
15671 Type& type = Type::Handle(); | 15698 Type& type = Type::Handle(); |
15672 if (!cls.IsGeneric()) { | 15699 if (!cls.IsGeneric()) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15743 return true; | 15770 return true; |
15744 } | 15771 } |
15745 } | 15772 } |
15746 if (!instantiated_other.IsFunctionType()) { | 15773 if (!instantiated_other.IsFunctionType()) { |
15747 return false; | 15774 return false; |
15748 } | 15775 } |
15749 Function& other_signature = | 15776 Function& other_signature = |
15750 Function::Handle(zone, Type::Cast(instantiated_other).signature()); | 15777 Function::Handle(zone, Type::Cast(instantiated_other).signature()); |
15751 Function& sig_fun = Function::Handle(zone, Closure::Cast(*this).function()); | 15778 Function& sig_fun = Function::Handle(zone, Closure::Cast(*this).function()); |
15752 if (!sig_fun.HasInstantiatedSignature()) { | 15779 if (!sig_fun.HasInstantiatedSignature()) { |
15753 const TypeArguments& instantiator_type_arguments = | 15780 const TypeArguments& instantiator_type_arguments = TypeArguments::Handle( |
15754 TypeArguments::Handle(zone, Closure::Cast(*this).instantiator()); | 15781 zone, Closure::Cast(*this).instantiator_type_arguments()); |
15755 const TypeArguments& function_type_arguments = | 15782 const TypeArguments& function_type_arguments = TypeArguments::Handle( |
15756 TypeArguments::Handle(zone, sig_fun.type_parameters()); | 15783 zone, Closure::Cast(*this).function_type_arguments()); |
15757 // TODO(regis): Pass the closure context to InstantiateSignatureFrom(). | |
15758 sig_fun = sig_fun.InstantiateSignatureFrom( | 15784 sig_fun = sig_fun.InstantiateSignatureFrom( |
15759 instantiator_type_arguments, function_type_arguments, Heap::kOld); | 15785 instantiator_type_arguments, function_type_arguments, Heap::kOld); |
15760 } | 15786 } |
15761 return sig_fun.IsSubtypeOf(other_signature, bound_error, Heap::kOld); | 15787 return sig_fun.IsSubtypeOf(other_signature, bound_error, Heap::kOld); |
15762 } | 15788 } |
15763 TypeArguments& type_arguments = TypeArguments::Handle(zone); | 15789 TypeArguments& type_arguments = TypeArguments::Handle(zone); |
15764 if (cls.NumTypeArguments() > 0) { | 15790 if (cls.NumTypeArguments() > 0) { |
15765 type_arguments = GetTypeArguments(); | 15791 type_arguments = GetTypeArguments(); |
15766 ASSERT(type_arguments.IsNull() || type_arguments.IsCanonical()); | 15792 ASSERT(type_arguments.IsNull() || type_arguments.IsCanonical()); |
15767 // The number of type arguments in the instance must be greater or equal to | 15793 // The number of type arguments in the instance must be greater or equal to |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16578 // For example, with class A<K, V extends K>, new A<T, T> called from within | 16604 // For example, with class A<K, V extends K>, new A<T, T> called from within |
16579 // a class B<T> will never require a run time bound check, even if T is | 16605 // a class B<T> will never require a run time bound check, even if T is |
16580 // uninstantiated at compile time. | 16606 // uninstantiated at compile time. |
16581 if (IsTypeParameter()) { | 16607 if (IsTypeParameter()) { |
16582 const TypeParameter& type_param = TypeParameter::Cast(*this); | 16608 const TypeParameter& type_param = TypeParameter::Cast(*this); |
16583 if (other.IsTypeParameter()) { | 16609 if (other.IsTypeParameter()) { |
16584 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 16610 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
16585 if (type_param.Equals(other_type_param)) { | 16611 if (type_param.Equals(other_type_param)) { |
16586 return true; | 16612 return true; |
16587 } | 16613 } |
| 16614 // TODO(regis): Should we update TypeParameter::IsEquivalent() instead? |
| 16615 if (type_param.IsFunctionTypeParameter() && |
| 16616 other_type_param.IsFunctionTypeParameter() && |
| 16617 type_param.IsFinalized() && other_type_param.IsFinalized() && |
| 16618 (type_param.index() == other_type_param.index())) { |
| 16619 return true; |
| 16620 } |
16588 } | 16621 } |
16589 const AbstractType& bound = AbstractType::Handle(zone, type_param.bound()); | 16622 const AbstractType& bound = AbstractType::Handle(zone, type_param.bound()); |
16590 // We may be checking bounds at finalization time and can encounter | 16623 // We may be checking bounds at finalization time and can encounter |
16591 // a still unfinalized bound. Finalizing the bound here may lead to cycles. | 16624 // a still unfinalized bound. Finalizing the bound here may lead to cycles. |
16592 if (!bound.IsFinalized()) { | 16625 if (!bound.IsFinalized()) { |
16593 return false; // TODO(regis): Return "maybe after instantiation". | 16626 return false; // TODO(regis): Return "maybe after instantiation". |
16594 } | 16627 } |
16595 // The current bound_trail cannot be used, because operands are swapped and | 16628 // The current bound_trail cannot be used, because operands are swapped and |
16596 // the test is different anyway (more specific vs. subtype). | 16629 // the test is different anyway (more specific vs. subtype). |
16597 if (bound.IsMoreSpecificThan(other, bound_error, NULL, space)) { | 16630 if (bound.IsMoreSpecificThan(other, bound_error, NULL, space)) { |
(...skipping 1191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17789 | 17822 |
17790 bool TypeParameter::IsInstantiated(Genericity genericity, | 17823 bool TypeParameter::IsInstantiated(Genericity genericity, |
17791 TrailPtr trail) const { | 17824 TrailPtr trail) const { |
17792 switch (genericity) { | 17825 switch (genericity) { |
17793 case kAny: | 17826 case kAny: |
17794 return false; | 17827 return false; |
17795 case kCurrentClass: | 17828 case kCurrentClass: |
17796 return IsFunctionTypeParameter(); | 17829 return IsFunctionTypeParameter(); |
17797 case kFunctions: | 17830 case kFunctions: |
17798 return IsClassTypeParameter(); | 17831 return IsClassTypeParameter(); |
17799 case kCurrentFunction: | |
17800 return IsClassTypeParameter() || (parent_level() > 0); | |
17801 case kParentFunctions: | |
17802 return IsClassTypeParameter() || (parent_level() == 0); | |
17803 default: | 17832 default: |
17804 UNREACHABLE(); | 17833 UNREACHABLE(); |
17805 } | 17834 } |
17806 return false; | 17835 return false; |
17807 } | 17836 } |
17808 | 17837 |
17809 | 17838 |
17810 bool TypeParameter::IsEquivalent(const Instance& other, TrailPtr trail) const { | 17839 bool TypeParameter::IsEquivalent(const Instance& other, TrailPtr trail) const { |
17811 if (raw() == other.raw()) { | 17840 if (raw() == other.raw()) { |
17812 return true; | 17841 return true; |
17813 } | 17842 } |
17814 if (other.IsTypeRef()) { | 17843 if (other.IsTypeRef()) { |
17815 // Unfold right hand type. Divergence is controlled by left hand type. | 17844 // Unfold right hand type. Divergence is controlled by left hand type. |
17816 const AbstractType& other_ref_type = | 17845 const AbstractType& other_ref_type = |
17817 AbstractType::Handle(TypeRef::Cast(other).type()); | 17846 AbstractType::Handle(TypeRef::Cast(other).type()); |
17818 ASSERT(!other_ref_type.IsTypeRef()); | 17847 ASSERT(!other_ref_type.IsTypeRef()); |
17819 return IsEquivalent(other_ref_type, trail); | 17848 return IsEquivalent(other_ref_type, trail); |
17820 } | 17849 } |
17821 if (!other.IsTypeParameter()) { | 17850 if (!other.IsTypeParameter()) { |
17822 return false; | 17851 return false; |
17823 } | 17852 } |
17824 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 17853 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
17825 if (parameterized_class_id() != other_type_param.parameterized_class_id()) { | 17854 if (parameterized_class_id() != other_type_param.parameterized_class_id()) { |
17826 return false; | 17855 return false; |
17827 } | 17856 } |
| 17857 // The function doesn't matter in type tests, but it does in canonicalization. |
17828 if (parameterized_function() != other_type_param.parameterized_function()) { | 17858 if (parameterized_function() != other_type_param.parameterized_function()) { |
17829 return false; | 17859 return false; |
17830 } | 17860 } |
17831 if (IsFinalized() == other_type_param.IsFinalized()) { | 17861 if (IsFinalized() == other_type_param.IsFinalized()) { |
17832 return (index() == other_type_param.index()) && | 17862 return (index() == other_type_param.index()); |
17833 (parent_level() == other_type_param.parent_level()); | |
17834 } | 17863 } |
17835 return name() == other_type_param.name(); | 17864 return name() == other_type_param.name(); |
17836 } | 17865 } |
17837 | 17866 |
17838 | 17867 |
17839 void TypeParameter::set_parameterized_class(const Class& value) const { | 17868 void TypeParameter::set_parameterized_class(const Class& value) const { |
17840 // Set value may be null. | 17869 // Set value may be null. |
17841 classid_t cid = kFunctionCid; // Denotes a function type parameter. | 17870 classid_t cid = kFunctionCid; // Denotes a function type parameter. |
17842 if (!value.IsNull()) { | 17871 if (!value.IsNull()) { |
17843 cid = value.id(); | 17872 cid = value.id(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17885 | 17914 |
17886 RawAbstractType* TypeParameter::InstantiateFrom( | 17915 RawAbstractType* TypeParameter::InstantiateFrom( |
17887 const TypeArguments& instantiator_type_arguments, | 17916 const TypeArguments& instantiator_type_arguments, |
17888 const TypeArguments& function_type_arguments, | 17917 const TypeArguments& function_type_arguments, |
17889 Error* bound_error, | 17918 Error* bound_error, |
17890 TrailPtr instantiation_trail, | 17919 TrailPtr instantiation_trail, |
17891 TrailPtr bound_trail, | 17920 TrailPtr bound_trail, |
17892 Heap::Space space) const { | 17921 Heap::Space space) const { |
17893 ASSERT(IsFinalized()); | 17922 ASSERT(IsFinalized()); |
17894 if (IsFunctionTypeParameter()) { | 17923 if (IsFunctionTypeParameter()) { |
17895 if (parent_level() == 0) { | 17924 // We make the distinction between a null function_type_arguments vector, |
17896 if (function_type_arguments.IsNull()) { | 17925 // which instantiates every function type parameter to dynamic, and a |
17897 return Type::DynamicType(); | 17926 // (possibly empty) function_type_arguments vector of length N, which only |
17898 } | 17927 // instantiates function type parameters with indices below N. |
17899 return function_type_arguments.TypeAt(index()); | 17928 if (function_type_arguments.IsNull()) { |
| 17929 return Type::DynamicType(); |
17900 } | 17930 } |
17901 // We need to find the type argument vector of the parent function at | 17931 if (index() >= function_type_arguments.Length()) { |
17902 // parent_level() in the context. | 17932 // Return uninstantiated type parameter unchanged. |
17903 UNIMPLEMENTED(); | 17933 return raw(); |
| 17934 } |
17904 return function_type_arguments.TypeAt(index()); | 17935 return function_type_arguments.TypeAt(index()); |
17905 } | 17936 } |
17906 ASSERT(IsClassTypeParameter()); | 17937 ASSERT(IsClassTypeParameter()); |
17907 if (instantiator_type_arguments.IsNull()) { | 17938 if (instantiator_type_arguments.IsNull()) { |
17908 return Type::DynamicType(); | 17939 return Type::DynamicType(); |
17909 } | 17940 } |
17910 return instantiator_type_arguments.TypeAt(index()); | 17941 return instantiator_type_arguments.TypeAt(index()); |
17911 // There is no need to canonicalize the instantiated type parameter, since all | 17942 // There is no need to canonicalize the instantiated type parameter, since all |
17912 // type arguments are canonicalized at type finalization time. It would be too | 17943 // type arguments are canonicalized at type finalization time. It would be too |
17913 // early to canonicalize the returned type argument here, since instantiation | 17944 // early to canonicalize the returned type argument here, since instantiation |
17914 // not only happens at run time, but also during type finalization. | 17945 // not only happens at run time, but also during type finalization. |
17915 | 17946 |
17916 // If the instantiated type parameter type_arg is a BoundedType, it means that | 17947 // If the instantiated type parameter type_arg is a BoundedType, it means that |
17917 // it is still uninstantiated and that we are instantiating at finalization | 17948 // it is still uninstantiated and that we are instantiating at finalization |
17918 // time (i.e. compile time). | 17949 // time (i.e. compile time). |
17919 // Indeed, the instantiator (type arguments of an instance) is always | 17950 // Indeed, the instantiator (type arguments of an instance) is always |
17920 // instantiated at run time and any bounds were checked during allocation. | 17951 // instantiated at run time and any bounds were checked during allocation. |
| 17952 // Similarly, function type arguments are always instantiated before being |
| 17953 // passed to a function at run time and bounds are checked as part of the |
| 17954 // signature compatibility check (during call resolution or in the function |
| 17955 // prolog). |
17921 } | 17956 } |
17922 | 17957 |
17923 | 17958 |
17924 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 17959 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
17925 const AbstractType& upper_bound, | 17960 const AbstractType& upper_bound, |
17926 Error* bound_error, | 17961 Error* bound_error, |
17927 TrailPtr bound_trail, | 17962 TrailPtr bound_trail, |
17928 Heap::Space space) const { | 17963 Heap::Space space) const { |
17929 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 17964 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
17930 ASSERT(bounded_type.IsFinalized()); | 17965 ASSERT(bounded_type.IsFinalized()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17984 } | 18019 } |
17985 | 18020 |
17986 | 18021 |
17987 RawAbstractType* TypeParameter::CloneUnfinalized() const { | 18022 RawAbstractType* TypeParameter::CloneUnfinalized() const { |
17988 if (IsFinalized()) { | 18023 if (IsFinalized()) { |
17989 return raw(); | 18024 return raw(); |
17990 } | 18025 } |
17991 // No need to clone bound, as it is not part of the finalization state. | 18026 // No need to clone bound, as it is not part of the finalization state. |
17992 return TypeParameter::New(Class::Handle(parameterized_class()), | 18027 return TypeParameter::New(Class::Handle(parameterized_class()), |
17993 Function::Handle(parameterized_function()), index(), | 18028 Function::Handle(parameterized_function()), index(), |
17994 parent_level(), String::Handle(name()), | 18029 String::Handle(name()), |
17995 AbstractType::Handle(bound()), token_pos()); | 18030 AbstractType::Handle(bound()), token_pos()); |
17996 } | 18031 } |
17997 | 18032 |
17998 | 18033 |
17999 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, | 18034 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, |
18000 TrailPtr trail) const { | 18035 TrailPtr trail) const { |
18001 ASSERT(IsFinalized()); | 18036 ASSERT(IsFinalized()); |
18002 TypeParameter& clone = TypeParameter::Handle(); | 18037 TypeParameter& clone = TypeParameter::Handle(); |
18003 clone ^= OnlyBuddyInTrail(trail); | 18038 clone ^= OnlyBuddyInTrail(trail); |
18004 if (!clone.IsNull()) { | 18039 if (!clone.IsNull()) { |
18005 return clone.raw(); | 18040 return clone.raw(); |
18006 } | 18041 } |
18007 const Class& old_owner = Class::Handle(parameterized_class()); | 18042 const Class& old_owner = Class::Handle(parameterized_class()); |
18008 if (old_owner.IsNull()) { | 18043 if (old_owner.IsNull()) { |
18009 ASSERT(IsFunctionTypeParameter()); | 18044 ASSERT(IsFunctionTypeParameter()); |
18010 // Function type parameters do not need cloning. | 18045 // Function type parameters do not need cloning. |
18011 return raw(); | 18046 return raw(); |
18012 } | 18047 } |
18013 const intptr_t new_index = | 18048 const intptr_t new_index = |
18014 index() + new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); | 18049 index() + new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); |
18015 AbstractType& upper_bound = AbstractType::Handle(bound()); | 18050 AbstractType& upper_bound = AbstractType::Handle(bound()); |
18016 ASSERT(parameterized_function() == Function::null()); | 18051 ASSERT(parameterized_function() == Function::null()); |
18017 clone = TypeParameter::New(new_owner, Function::Handle(), new_index, 0, | 18052 clone = TypeParameter::New(new_owner, Function::Handle(), new_index, |
18018 String::Handle(name()), | 18053 String::Handle(name()), |
18019 upper_bound, // Not cloned yet. | 18054 upper_bound, // Not cloned yet. |
18020 token_pos()); | 18055 token_pos()); |
18021 clone.SetIsFinalized(); | 18056 clone.SetIsFinalized(); |
18022 AddOnlyBuddyToTrail(&trail, clone); | 18057 AddOnlyBuddyToTrail(&trail, clone); |
18023 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | 18058 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); |
18024 clone.set_bound(upper_bound); | 18059 clone.set_bound(upper_bound); |
18025 return clone.raw(); | 18060 return clone.raw(); |
18026 } | 18061 } |
18027 | 18062 |
18028 | 18063 |
18029 RawString* TypeParameter::EnumerateURIs() const { | 18064 RawString* TypeParameter::EnumerateURIs() const { |
18030 Thread* thread = Thread::Current(); | 18065 Thread* thread = Thread::Current(); |
18031 Zone* zone = thread->zone(); | 18066 Zone* zone = thread->zone(); |
18032 GrowableHandlePtrArray<const String> pieces(zone, 4); | 18067 GrowableHandlePtrArray<const String> pieces(zone, 4); |
18033 pieces.Add(Symbols::TwoSpaces()); | 18068 pieces.Add(Symbols::TwoSpaces()); |
18034 pieces.Add(String::Handle(zone, name())); | 18069 pieces.Add(String::Handle(zone, name())); |
18035 pieces.Add(Symbols::SpaceOfSpace()); | 18070 Class& cls = Class::Handle(zone, parameterized_class()); |
18036 const Class& cls = Class::Handle(zone, parameterized_class()); | 18071 if (cls.IsNull()) { |
18037 pieces.Add(String::Handle(zone, cls.UserVisibleName())); | 18072 const Function& fun = Function::Handle(zone, parameterized_function()); |
18038 pieces.Add(Symbols::SpaceIsFromSpace()); | 18073 pieces.Add(Symbols::SpaceOfSpace()); |
18039 const Library& library = Library::Handle(zone, cls.library()); | 18074 pieces.Add(String::Handle(zone, fun.UserVisibleName())); |
18040 pieces.Add(String::Handle(zone, library.url())); | 18075 cls = fun.Owner(); // May be null. |
| 18076 // TODO(regis): Should we keep the function owner for better error messages? |
| 18077 } |
| 18078 if (!cls.IsNull()) { |
| 18079 pieces.Add(Symbols::SpaceOfSpace()); |
| 18080 pieces.Add(String::Handle(zone, cls.UserVisibleName())); |
| 18081 pieces.Add(Symbols::SpaceIsFromSpace()); |
| 18082 const Library& library = Library::Handle(zone, cls.library()); |
| 18083 pieces.Add(String::Handle(zone, library.url())); |
| 18084 } |
18041 pieces.Add(Symbols::NewLine()); | 18085 pieces.Add(Symbols::NewLine()); |
18042 return Symbols::FromConcatAll(thread, pieces); | 18086 return Symbols::FromConcatAll(thread, pieces); |
18043 } | 18087 } |
18044 | 18088 |
18045 | 18089 |
18046 intptr_t TypeParameter::ComputeHash() const { | 18090 intptr_t TypeParameter::ComputeHash() const { |
18047 ASSERT(IsFinalized()); | 18091 ASSERT(IsFinalized()); |
18048 uint32_t result; | 18092 uint32_t result; |
18049 if (IsClassTypeParameter()) { | 18093 if (IsClassTypeParameter()) { |
18050 result = parameterized_class_id(); | 18094 result = parameterized_class_id(); |
18051 } else { | 18095 } else { |
18052 result = Function::Handle(parameterized_function()).Hash(); | 18096 result = Function::Handle(parameterized_function()).Hash(); |
18053 result = CombineHashes(result, parent_level()); | |
18054 } | 18097 } |
18055 // No need to include the hash of the bound, since the type parameter is fully | 18098 // No need to include the hash of the bound, since the type parameter is fully |
18056 // identified by its class and index. | 18099 // identified by its class and index. |
18057 result = CombineHashes(result, index()); | 18100 result = CombineHashes(result, index()); |
18058 result = FinalizeHash(result, kHashBits); | 18101 result = FinalizeHash(result, kHashBits); |
18059 SetHash(result); | 18102 SetHash(result); |
18060 return result; | 18103 return result; |
18061 } | 18104 } |
18062 | 18105 |
18063 | 18106 |
18064 RawTypeParameter* TypeParameter::New() { | 18107 RawTypeParameter* TypeParameter::New() { |
18065 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 18108 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
18066 TypeParameter::InstanceSize(), Heap::kOld); | 18109 TypeParameter::InstanceSize(), Heap::kOld); |
18067 return reinterpret_cast<RawTypeParameter*>(raw); | 18110 return reinterpret_cast<RawTypeParameter*>(raw); |
18068 } | 18111 } |
18069 | 18112 |
18070 | 18113 |
18071 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, | 18114 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, |
18072 const Function& parameterized_function, | 18115 const Function& parameterized_function, |
18073 intptr_t index, | 18116 intptr_t index, |
18074 intptr_t parent_level, | |
18075 const String& name, | 18117 const String& name, |
18076 const AbstractType& bound, | 18118 const AbstractType& bound, |
18077 TokenPosition token_pos) { | 18119 TokenPosition token_pos) { |
18078 ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); | 18120 ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); |
18079 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); | 18121 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); |
18080 result.set_parameterized_class(parameterized_class); | 18122 result.set_parameterized_class(parameterized_class); |
18081 result.set_parameterized_function(parameterized_function); | 18123 result.set_parameterized_function(parameterized_function); |
18082 result.set_index(index); | 18124 result.set_index(index); |
18083 result.set_parent_level(parent_level); | |
18084 result.set_name(name); | 18125 result.set_name(name); |
18085 result.set_bound(bound); | 18126 result.set_bound(bound); |
18086 result.SetHash(0); | 18127 result.SetHash(0); |
18087 result.set_token_pos(token_pos); | 18128 result.set_token_pos(token_pos); |
18088 result.StoreNonPointer(&result.raw_ptr()->type_state_, | 18129 result.StoreNonPointer(&result.raw_ptr()->type_state_, |
18089 RawTypeParameter::kAllocated); | 18130 RawTypeParameter::kAllocated); |
18090 return result.raw(); | 18131 return result.raw(); |
18091 } | 18132 } |
18092 | 18133 |
18093 | 18134 |
18094 void TypeParameter::set_token_pos(TokenPosition token_pos) const { | 18135 void TypeParameter::set_token_pos(TokenPosition token_pos) const { |
18095 ASSERT(!token_pos.IsClassifying()); | 18136 ASSERT(!token_pos.IsClassifying()); |
18096 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 18137 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |
18097 } | 18138 } |
18098 | 18139 |
18099 | 18140 |
18100 void TypeParameter::set_parent_level(intptr_t value) const { | |
18101 // TODO(regis): Report error in caller if not uint8. | |
18102 ASSERT(Utils::IsUint(8, value)); | |
18103 StoreNonPointer(&raw_ptr()->parent_level_, value); | |
18104 } | |
18105 | |
18106 | |
18107 void TypeParameter::set_type_state(int8_t state) const { | 18141 void TypeParameter::set_type_state(int8_t state) const { |
18108 ASSERT((state == RawTypeParameter::kAllocated) || | 18142 ASSERT((state == RawTypeParameter::kAllocated) || |
18109 (state == RawTypeParameter::kBeingFinalized) || | 18143 (state == RawTypeParameter::kBeingFinalized) || |
18110 (state == RawTypeParameter::kFinalizedUninstantiated)); | 18144 (state == RawTypeParameter::kFinalizedUninstantiated)); |
18111 StoreNonPointer(&raw_ptr()->type_state_, state); | 18145 StoreNonPointer(&raw_ptr()->type_state_, state); |
18112 } | 18146 } |
18113 | 18147 |
18114 | 18148 |
18115 const char* TypeParameter::ToCString() const { | 18149 const char* TypeParameter::ToCString() const { |
18116 const char* name_cstr = String::Handle(Name()).ToCString(); | 18150 const char* name_cstr = String::Handle(Name()).ToCString(); |
18117 const AbstractType& upper_bound = AbstractType::Handle(bound()); | 18151 const AbstractType& upper_bound = AbstractType::Handle(bound()); |
18118 const char* bound_cstr = String::Handle(upper_bound.Name()).ToCString(); | 18152 const char* bound_cstr = String::Handle(upper_bound.Name()).ToCString(); |
18119 if (IsFunctionTypeParameter()) { | 18153 if (IsFunctionTypeParameter()) { |
18120 const char* format = | 18154 const char* format = |
18121 "TypeParameter: name %s; index: %d; parent_level: %d, " | 18155 "TypeParameter: name %s; index: %d; function: %s; bound: %s"; |
18122 "function: %s; bound: %s"; | |
18123 const Function& function = Function::Handle(parameterized_function()); | 18156 const Function& function = Function::Handle(parameterized_function()); |
18124 const char* fun_cstr = String::Handle(function.name()).ToCString(); | 18157 const char* fun_cstr = String::Handle(function.name()).ToCString(); |
18125 intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, index(), | 18158 intptr_t len = |
18126 parent_level(), fun_cstr, bound_cstr) + | 18159 OS::SNPrint(NULL, 0, format, name_cstr, index(), fun_cstr, bound_cstr) + |
18127 1; | 18160 1; |
18128 char* chars = Thread::Current()->zone()->Alloc<char>(len); | 18161 char* chars = Thread::Current()->zone()->Alloc<char>(len); |
18129 OS::SNPrint(chars, len, format, name_cstr, index(), parent_level(), | 18162 OS::SNPrint(chars, len, format, name_cstr, index(), fun_cstr, bound_cstr); |
18130 fun_cstr, bound_cstr); | |
18131 return chars; | 18163 return chars; |
18132 } else { | 18164 } else { |
18133 const char* format = | 18165 const char* format = |
18134 "TypeParameter: name %s; index: %d; class: %s; bound: %s"; | 18166 "TypeParameter: name %s; index: %d; class: %s; bound: %s"; |
18135 const Class& cls = Class::Handle(parameterized_class()); | 18167 const Class& cls = Class::Handle(parameterized_class()); |
18136 const char* cls_cstr = | 18168 const char* cls_cstr = |
18137 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); | 18169 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); |
18138 intptr_t len = | 18170 intptr_t len = |
18139 OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr, bound_cstr) + | 18171 OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr, bound_cstr) + |
18140 1; | 18172 1; |
(...skipping 4380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22521 const Function& fun = Function::Handle(function()); | 22553 const Function& fun = Function::Handle(function()); |
22522 const bool is_implicit_closure = fun.IsImplicitClosureFunction(); | 22554 const bool is_implicit_closure = fun.IsImplicitClosureFunction(); |
22523 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); | 22555 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); |
22524 const char* from = is_implicit_closure ? " from " : ""; | 22556 const char* from = is_implicit_closure ? " from " : ""; |
22525 const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; | 22557 const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; |
22526 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, | 22558 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, |
22527 from, fun_desc); | 22559 from, fun_desc); |
22528 } | 22560 } |
22529 | 22561 |
22530 | 22562 |
22531 RawClosure* Closure::New(const TypeArguments& instantiator, | 22563 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments, |
| 22564 const TypeArguments& function_type_arguments, |
22532 const Function& function, | 22565 const Function& function, |
22533 const Context& context, | 22566 const Context& context, |
22534 Heap::Space space) { | 22567 Heap::Space space) { |
22535 Closure& result = Closure::Handle(); | 22568 Closure& result = Closure::Handle(); |
22536 { | 22569 { |
22537 RawObject* raw = | 22570 RawObject* raw = |
22538 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); | 22571 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); |
22539 NoSafepointScope no_safepoint; | 22572 NoSafepointScope no_safepoint; |
22540 result ^= raw; | 22573 result ^= raw; |
22541 result.StorePointer(&result.raw_ptr()->instantiator_, instantiator.raw()); | 22574 result.StorePointer(&result.raw_ptr()->instantiator_type_arguments_, |
| 22575 instantiator_type_arguments.raw()); |
| 22576 result.StorePointer(&result.raw_ptr()->function_type_arguments_, |
| 22577 function_type_arguments.raw()); |
22542 result.StorePointer(&result.raw_ptr()->function_, function.raw()); | 22578 result.StorePointer(&result.raw_ptr()->function_, function.raw()); |
22543 result.StorePointer(&result.raw_ptr()->context_, context.raw()); | 22579 result.StorePointer(&result.raw_ptr()->context_, context.raw()); |
22544 } | 22580 } |
22545 return result.raw(); | 22581 return result.raw(); |
22546 } | 22582 } |
22547 | 22583 |
22548 | 22584 |
22549 RawClosure* Closure::New() { | 22585 RawClosure* Closure::New() { |
22550 RawObject* raw = | 22586 RawObject* raw = |
22551 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld); | 22587 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld); |
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
23147 return UserTag::null(); | 23183 return UserTag::null(); |
23148 } | 23184 } |
23149 | 23185 |
23150 | 23186 |
23151 const char* UserTag::ToCString() const { | 23187 const char* UserTag::ToCString() const { |
23152 const String& tag_label = String::Handle(label()); | 23188 const String& tag_label = String::Handle(label()); |
23153 return tag_label.ToCString(); | 23189 return tag_label.ToCString(); |
23154 } | 23190 } |
23155 | 23191 |
23156 } // namespace dart | 23192 } // namespace dart |
OLD | NEW |