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

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

Issue 2696783002: Properly resolve upper bounds of generic function's type parameters. (Closed)
Patch Set: Created 3 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/become.h" 10 #include "vm/become.h"
(...skipping 5887 matching lines...) Expand 10 before | Expand all | Expand 10 after
5898 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); 5898 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread);
5899 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); 5899 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread);
5900 REUSABLE_STRING_HANDLESCOPE(thread); 5900 REUSABLE_STRING_HANDLESCOPE(thread);
5901 REUSABLE_FUNCTION_HANDLESCOPE(thread); 5901 REUSABLE_FUNCTION_HANDLESCOPE(thread);
5902 TypeArguments& type_params = thread->TypeArgumentsHandle(); 5902 TypeArguments& type_params = thread->TypeArgumentsHandle();
5903 TypeParameter& type_param = thread->TypeParameterHandle(); 5903 TypeParameter& type_param = thread->TypeParameterHandle();
5904 String& type_param_name = thread->StringHandle(); 5904 String& type_param_name = thread->StringHandle();
5905 Function& function = thread->FunctionHandle(); 5905 Function& function = thread->FunctionHandle();
5906 5906
5907 function ^= this->raw(); 5907 function ^= this->raw();
5908 intptr_t parent_level = -1; 5908 intptr_t parent_level = 0;
5909 while (!function.IsNull()) { 5909 while (!function.IsNull()) {
5910 type_params ^= function.type_parameters(); 5910 type_params ^= function.type_parameters();
5911 if (!type_params.IsNull()) { 5911 if (!type_params.IsNull()) {
5912 parent_level++;
5913 const intptr_t num_type_params = type_params.Length(); 5912 const intptr_t num_type_params = type_params.Length();
5914 for (intptr_t i = 0; i < num_type_params; i++) { 5913 for (intptr_t i = 0; i < num_type_params; i++) {
5915 type_param ^= type_params.TypeAt(i); 5914 type_param ^= type_params.TypeAt(i);
5916 type_param_name = type_param.name(); 5915 type_param_name = type_param.name();
5917 if (type_param_name.Equals(type_name)) { 5916 if (type_param_name.Equals(type_name)) {
5918 if (parent_level > 0) { 5917 if (parent_level > 0) {
5919 // TODO(regis): Clone type parameter and set parent_level. 5918 // Clone type parameter and set parent_level.
5919 return TypeParameter::New(
5920 Class::Handle(), function, type_param.index(), parent_level,
5921 type_param_name, AbstractType::Handle(type_param.bound()),
5922 TokenPosition::kNoSource);
5920 } 5923 }
5921 return type_param.raw(); 5924 return type_param.raw();
5922 } 5925 }
5923 } 5926 }
5924 } 5927 }
5925 function ^= function.parent_function(); 5928 function ^= function.parent_function();
5929 parent_level++;
5926 if (function_level != NULL) { 5930 if (function_level != NULL) {
5927 (*function_level)--; 5931 (*function_level)--;
5928 } 5932 }
5929 } 5933 }
5930 return TypeParameter::null(); 5934 return TypeParameter::null();
5931 } 5935 }
5932 5936
5933 5937
5934 void Function::set_kind(RawFunction::Kind value) const { 5938 void Function::set_kind(RawFunction::Kind value) const {
5935 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); 5939 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_));
(...skipping 9658 matching lines...) Expand 10 before | Expand all | Expand 10 after
15594 if (!other.IsFunctionType()) { 15598 if (!other.IsFunctionType()) {
15595 return false; 15599 return false;
15596 } 15600 }
15597 other_signature = Type::Cast(other).signature(); 15601 other_signature = Type::Cast(other).signature();
15598 other_type_arguments = other.arguments(); 15602 other_type_arguments = other.arguments();
15599 } 15603 }
15600 const Function& signature = 15604 const Function& signature =
15601 Function::Handle(zone, Closure::Cast(*this).function()); 15605 Function::Handle(zone, Closure::Cast(*this).function());
15602 const TypeArguments& type_arguments = 15606 const TypeArguments& type_arguments =
15603 TypeArguments::Handle(zone, GetTypeArguments()); 15607 TypeArguments::Handle(zone, GetTypeArguments());
15608 // TODO(regis): If signature function is generic, pass its type parameters
15609 // as function instantiator, otherwise pass null.
15610 // Pass the closure context as well to the the IsSubtypeOf call.
15604 return signature.IsSubtypeOf(type_arguments, other_signature, 15611 return signature.IsSubtypeOf(type_arguments, other_signature,
15605 other_type_arguments, bound_error, Heap::kOld); 15612 other_type_arguments, bound_error, Heap::kOld);
15606 } 15613 }
15607 TypeArguments& type_arguments = TypeArguments::Handle(zone); 15614 TypeArguments& type_arguments = TypeArguments::Handle(zone);
15608 if (cls.NumTypeArguments() > 0) { 15615 if (cls.NumTypeArguments() > 0) {
15609 type_arguments = GetTypeArguments(); 15616 type_arguments = GetTypeArguments();
15610 ASSERT(type_arguments.IsNull() || type_arguments.IsCanonical()); 15617 ASSERT(type_arguments.IsNull() || type_arguments.IsCanonical());
15611 // The number of type arguments in the instance must be greater or equal to 15618 // The number of type arguments in the instance must be greater or equal to
15612 // the number of type arguments expected by the instance class. 15619 // the number of type arguments expected by the instance class.
15613 // A discrepancy is allowed for closures, which borrow the type argument 15620 // A discrepancy is allowed for closures, which borrow the type argument
(...skipping 2154 matching lines...) Expand 10 before | Expand all | Expand 10 after
17768 } 17775 }
17769 17776
17770 17777
17771 RawAbstractType* TypeParameter::CloneUnfinalized() const { 17778 RawAbstractType* TypeParameter::CloneUnfinalized() const {
17772 if (IsFinalized()) { 17779 if (IsFinalized()) {
17773 return raw(); 17780 return raw();
17774 } 17781 }
17775 // No need to clone bound, as it is not part of the finalization state. 17782 // No need to clone bound, as it is not part of the finalization state.
17776 return TypeParameter::New(Class::Handle(parameterized_class()), 17783 return TypeParameter::New(Class::Handle(parameterized_class()),
17777 Function::Handle(parameterized_function()), index(), 17784 Function::Handle(parameterized_function()), index(),
17778 String::Handle(name()), 17785 parent_level(), String::Handle(name()),
17779 AbstractType::Handle(bound()), token_pos()); 17786 AbstractType::Handle(bound()), token_pos());
17780 } 17787 }
17781 17788
17782 17789
17783 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, 17790 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner,
17784 TrailPtr trail) const { 17791 TrailPtr trail) const {
17785 ASSERT(IsFinalized()); 17792 ASSERT(IsFinalized());
17786 TypeParameter& clone = TypeParameter::Handle(); 17793 TypeParameter& clone = TypeParameter::Handle();
17787 clone ^= OnlyBuddyInTrail(trail); 17794 clone ^= OnlyBuddyInTrail(trail);
17788 if (!clone.IsNull()) { 17795 if (!clone.IsNull()) {
17789 return clone.raw(); 17796 return clone.raw();
17790 } 17797 }
17791 const Class& old_owner = Class::Handle(parameterized_class()); 17798 const Class& old_owner = Class::Handle(parameterized_class());
17799 if (old_owner.IsNull()) {
17800 ASSERT(IsFunctionTypeParameter());
17801 // Function type parameters do not need cloning.
17802 return raw();
17803 }
17792 const intptr_t new_index = 17804 const intptr_t new_index =
17793 index() + new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); 17805 index() + new_owner.NumTypeArguments() - old_owner.NumTypeArguments();
17794 AbstractType& upper_bound = AbstractType::Handle(bound()); 17806 AbstractType& upper_bound = AbstractType::Handle(bound());
17795 ASSERT(parameterized_function() == Function::null()); 17807 ASSERT(parameterized_function() == Function::null());
17796 clone = TypeParameter::New(new_owner, Function::Handle(), new_index, 17808 clone = TypeParameter::New(new_owner, Function::Handle(), new_index, 0,
17797 String::Handle(name()), 17809 String::Handle(name()),
17798 upper_bound, // Not cloned yet. 17810 upper_bound, // Not cloned yet.
17799 token_pos()); 17811 token_pos());
17800 clone.SetIsFinalized(); 17812 clone.SetIsFinalized();
17801 AddOnlyBuddyToTrail(&trail, clone); 17813 AddOnlyBuddyToTrail(&trail, clone);
17802 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); 17814 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail);
17803 clone.set_bound(upper_bound); 17815 clone.set_bound(upper_bound);
17804 return clone.raw(); 17816 return clone.raw();
17805 } 17817 }
17806 17818
(...skipping 30 matching lines...) Expand all
17837 RawTypeParameter* TypeParameter::New() { 17849 RawTypeParameter* TypeParameter::New() {
17838 RawObject* raw = Object::Allocate(TypeParameter::kClassId, 17850 RawObject* raw = Object::Allocate(TypeParameter::kClassId,
17839 TypeParameter::InstanceSize(), Heap::kOld); 17851 TypeParameter::InstanceSize(), Heap::kOld);
17840 return reinterpret_cast<RawTypeParameter*>(raw); 17852 return reinterpret_cast<RawTypeParameter*>(raw);
17841 } 17853 }
17842 17854
17843 17855
17844 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, 17856 RawTypeParameter* TypeParameter::New(const Class& parameterized_class,
17845 const Function& parameterized_function, 17857 const Function& parameterized_function,
17846 intptr_t index, 17858 intptr_t index,
17859 intptr_t parent_level,
17847 const String& name, 17860 const String& name,
17848 const AbstractType& bound, 17861 const AbstractType& bound,
17849 TokenPosition token_pos) { 17862 TokenPosition token_pos) {
17850 ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); 17863 ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull());
17851 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); 17864 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New());
17852 result.set_parameterized_class(parameterized_class); 17865 result.set_parameterized_class(parameterized_class);
17853 result.set_parameterized_function(parameterized_function); 17866 result.set_parameterized_function(parameterized_function);
17854 result.set_index(index); 17867 result.set_index(index);
17868 result.set_parent_level(parent_level);
17855 result.set_name(name); 17869 result.set_name(name);
17856 result.set_bound(bound); 17870 result.set_bound(bound);
17857 result.SetHash(0); 17871 result.SetHash(0);
17858 result.set_token_pos(token_pos); 17872 result.set_token_pos(token_pos);
17859 result.StoreNonPointer(&result.raw_ptr()->type_state_, 17873 result.StoreNonPointer(&result.raw_ptr()->type_state_,
17860 RawTypeParameter::kAllocated); 17874 RawTypeParameter::kAllocated);
17861 return result.raw(); 17875 return result.raw();
17862 } 17876 }
17863 17877
17864 17878
17865 void TypeParameter::set_token_pos(TokenPosition token_pos) const { 17879 void TypeParameter::set_token_pos(TokenPosition token_pos) const {
17866 ASSERT(!token_pos.IsClassifying()); 17880 ASSERT(!token_pos.IsClassifying());
17867 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); 17881 StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
17868 } 17882 }
17869 17883
17870 17884
17871 void TypeParameter::set_parent_level(uint8_t value) const { 17885 void TypeParameter::set_parent_level(intptr_t value) const {
17886 // TODO(regis): Report error in caller if not uint8.
17887 ASSERT(Utils::IsUint(8, value));
17872 StoreNonPointer(&raw_ptr()->parent_level_, value); 17888 StoreNonPointer(&raw_ptr()->parent_level_, value);
17873 } 17889 }
17874 17890
17875 17891
17876 void TypeParameter::set_type_state(int8_t state) const { 17892 void TypeParameter::set_type_state(int8_t state) const {
17877 ASSERT((state == RawTypeParameter::kAllocated) || 17893 ASSERT((state == RawTypeParameter::kAllocated) ||
17878 (state == RawTypeParameter::kBeingFinalized) || 17894 (state == RawTypeParameter::kBeingFinalized) ||
17879 (state == RawTypeParameter::kFinalizedUninstantiated)); 17895 (state == RawTypeParameter::kFinalizedUninstantiated));
17880 StoreNonPointer(&raw_ptr()->type_state_, state); 17896 StoreNonPointer(&raw_ptr()->type_state_, state);
17881 } 17897 }
(...skipping 4928 matching lines...) Expand 10 before | Expand all | Expand 10 after
22810 return UserTag::null(); 22826 return UserTag::null();
22811 } 22827 }
22812 22828
22813 22829
22814 const char* UserTag::ToCString() const { 22830 const char* UserTag::ToCString() const {
22815 const String& tag_label = String::Handle(label()); 22831 const String& tag_label = String::Handle(label());
22816 return tag_label.ToCString(); 22832 return tag_label.ToCString();
22817 } 22833 }
22818 22834
22819 } // namespace dart 22835 } // 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