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

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

Issue 2835513002: Process generic function type arguments in more places (function type tests, (Closed)
Patch Set: Created 3 years, 8 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 | « no previous file | 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "vm/thread_registry.h" 45 #include "vm/thread_registry.h"
46 #include "vm/timeline.h" 46 #include "vm/timeline.h"
47 #include "vm/timer.h" 47 #include "vm/timer.h"
48 #include "vm/type_table.h" 48 #include "vm/type_table.h"
49 #include "vm/unicode.h" 49 #include "vm/unicode.h"
50 #include "vm/weak_code.h" 50 #include "vm/weak_code.h"
51 #include "vm/zone_text_buffer.h" 51 #include "vm/zone_text_buffer.h"
52 52
53 namespace dart { 53 namespace dart {
54 54
55 DEFINE_FLAG(bool,
zra 2017/04/20 19:22:09 Should we put this in flag_list.h?
regis 2017/04/20 20:23:30 Done.
56 reify_generic_functions,
57 false,
58 "Enable reification of generic functions (not yet supported).");
55 DEFINE_FLAG(int, 59 DEFINE_FLAG(int,
56 huge_method_cutoff_in_code_size, 60 huge_method_cutoff_in_code_size,
57 200000, 61 200000,
58 "Huge method cutoff in unoptimized code size (in bytes)."); 62 "Huge method cutoff in unoptimized code size (in bytes).");
59 DEFINE_FLAG( 63 DEFINE_FLAG(
60 bool, 64 bool,
61 overlap_type_arguments, 65 overlap_type_arguments,
62 true, 66 true,
63 "When possible, partially or fully overlap the type arguments of a type " 67 "When possible, partially or fully overlap the type arguments of a type "
64 "with the type arguments of its super type."); 68 "with the type arguments of its super type.");
(...skipping 6360 matching lines...) Expand 10 before | Expand all | Expand 10 after
6425 return chars; 6429 return chars;
6426 } 6430 }
6427 6431
6428 6432
6429 bool Function::HasCompatibleParametersWith(const Function& other, 6433 bool Function::HasCompatibleParametersWith(const Function& other,
6430 Error* bound_error) const { 6434 Error* bound_error) const {
6431 ASSERT(Isolate::Current()->error_on_bad_override()); 6435 ASSERT(Isolate::Current()->error_on_bad_override());
6432 ASSERT((bound_error != NULL) && bound_error->IsNull()); 6436 ASSERT((bound_error != NULL) && bound_error->IsNull());
6433 // Check that this function's signature type is a subtype of the other 6437 // Check that this function's signature type is a subtype of the other
6434 // function's signature type. 6438 // function's signature type.
6435 // Map type parameters in the signature to dynamic before the test. 6439 // Map type parameters referred to by formal parameter types and result type
6440 // in the signature to dynamic before the test.
6441 // Note that type parameters declared by a generic signature are preserved.
6436 Function& this_fun = Function::Handle(raw()); 6442 Function& this_fun = Function::Handle(raw());
6437 if (!this_fun.HasInstantiatedSignature()) { 6443 if (!this_fun.HasInstantiatedSignature()) {
6438 // TODO(regis): Should we pass the context explicitly here (i.e. null) once
6439 // we support generic functions?
6440 this_fun = this_fun.InstantiateSignatureFrom(Object::null_type_arguments(), 6444 this_fun = this_fun.InstantiateSignatureFrom(Object::null_type_arguments(),
6441 Object::null_type_arguments(), 6445 Object::null_type_arguments(),
6442 Heap::kOld); 6446 Heap::kOld);
6443 } 6447 }
6444 Function& other_fun = Function::Handle(other.raw()); 6448 Function& other_fun = Function::Handle(other.raw());
6445 if (!other_fun.HasInstantiatedSignature()) { 6449 if (!other_fun.HasInstantiatedSignature()) {
6446 // TODO(regis): Should we pass the context explicitly here (i.e. null) once
6447 // we support generic functions?
6448 other_fun = other_fun.InstantiateSignatureFrom( 6450 other_fun = other_fun.InstantiateSignatureFrom(
6449 Object::null_type_arguments(), Object::null_type_arguments(), 6451 Object::null_type_arguments(), Object::null_type_arguments(),
6450 Heap::kOld); 6452 Heap::kOld);
6451 } 6453 }
6452 if (!this_fun.TypeTest(kIsSubtypeOf, other_fun, bound_error, Heap::kOld)) { 6454 if (!this_fun.TypeTest(kIsSubtypeOf, other_fun, bound_error, Heap::kOld)) {
6453 // For more informative error reporting, use the location of the other 6455 // For more informative error reporting, use the location of the other
6454 // function here, since the caller will use the location of this function. 6456 // function here, since the caller will use the location of this function.
6455 *bound_error = LanguageError::NewFormatted( 6457 *bound_error = LanguageError::NewFormatted(
6456 *bound_error, // A bound error if non null. 6458 *bound_error, // A bound error if non null.
6457 Script::Handle(other.script()), other.token_pos(), Report::AtLocation, 6459 Script::Handle(other.script()), other.token_pos(), Report::AtLocation,
(...skipping 19 matching lines...) Expand all
6477 RawFunction* Function::InstantiateSignatureFrom( 6479 RawFunction* Function::InstantiateSignatureFrom(
6478 const TypeArguments& instantiator_type_arguments, 6480 const TypeArguments& instantiator_type_arguments,
6479 const TypeArguments& function_type_arguments, 6481 const TypeArguments& function_type_arguments,
6480 Heap::Space space) const { 6482 Heap::Space space) const {
6481 Zone* zone = Thread::Current()->zone(); 6483 Zone* zone = Thread::Current()->zone();
6482 const Object& owner = Object::Handle(zone, RawOwner()); 6484 const Object& owner = Object::Handle(zone, RawOwner());
6483 ASSERT(!HasInstantiatedSignature()); 6485 ASSERT(!HasInstantiatedSignature());
6484 Function& sig = Function::Handle( 6486 Function& sig = Function::Handle(
6485 zone, 6487 zone,
6486 Function::NewSignatureFunction(owner, TokenPosition::kNoSource, space)); 6488 Function::NewSignatureFunction(owner, TokenPosition::kNoSource, space));
6487 // TODO(regis): If type parameter bounds are not IsInstantiated(kFunctions),
6488 // clone finalized type parameters and instantiate bounds.
6489 sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters())); 6489 sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
6490 AbstractType& type = AbstractType::Handle(zone, result_type()); 6490 AbstractType& type = AbstractType::Handle(zone, result_type());
6491 if (!type.IsInstantiated()) { 6491 if (!type.IsInstantiated()) {
6492 type = 6492 type =
6493 type.InstantiateFrom(instantiator_type_arguments, 6493 type.InstantiateFrom(instantiator_type_arguments,
6494 function_type_arguments, NULL, NULL, NULL, space); 6494 function_type_arguments, NULL, NULL, NULL, space);
6495 } 6495 }
6496 sig.set_result_type(type); 6496 sig.set_result_type(type);
6497 const intptr_t num_params = NumParameters(); 6497 const intptr_t num_params = NumParameters();
6498 sig.set_num_fixed_parameters(num_fixed_parameters()); 6498 sig.set_num_fixed_parameters(num_fixed_parameters());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
6570 const intptr_t num_ignored_params = NumImplicitParameters(); 6570 const intptr_t num_ignored_params = NumImplicitParameters();
6571 const intptr_t other_num_ignored_params = other.NumImplicitParameters(); 6571 const intptr_t other_num_ignored_params = other.NumImplicitParameters();
6572 if (((num_fixed_params - num_ignored_params) > 6572 if (((num_fixed_params - num_ignored_params) >
6573 (other_num_fixed_params - other_num_ignored_params)) || 6573 (other_num_fixed_params - other_num_ignored_params)) ||
6574 ((num_fixed_params - num_ignored_params + num_opt_pos_params) < 6574 ((num_fixed_params - num_ignored_params + num_opt_pos_params) <
6575 (other_num_fixed_params - other_num_ignored_params + 6575 (other_num_fixed_params - other_num_ignored_params +
6576 other_num_opt_pos_params)) || 6576 other_num_opt_pos_params)) ||
6577 (num_opt_named_params < other_num_opt_named_params)) { 6577 (num_opt_named_params < other_num_opt_named_params)) {
6578 return false; 6578 return false;
6579 } 6579 }
6580 6580 Thread* thread = Thread::Current();
6581 // TODO(regis): Check the type parameters and bounds of a generic function. 6581 Zone* zone = thread->zone();
6582 6582 if (FLAG_reify_generic_functions) {
6583 // Check the type parameters and bounds of a generic function.
6584 const intptr_t num_type_params = NumTypeParameters(thread);
6585 if (num_type_params != other.NumTypeParameters(thread)) {
6586 return false;
6587 }
6588 if (num_type_params > 0) {
6589 const TypeArguments& type_params =
6590 TypeArguments::Handle(zone, type_parameters());
6591 ASSERT(!type_params.IsNull());
6592 const TypeArguments& other_type_params =
6593 TypeArguments::Handle(zone, other.type_parameters());
6594 ASSERT(!other_type_params.IsNull());
6595 TypeParameter& type_param = TypeParameter::Handle(zone);
6596 TypeParameter& other_type_param = TypeParameter::Handle(zone);
6597 AbstractType& bound = AbstractType::Handle(zone);
6598 AbstractType& other_bound = AbstractType::Handle(zone);
6599 for (intptr_t i = 0; i < num_type_params; i++) {
6600 type_param ^= type_params.TypeAt(i);
6601 other_type_param ^= other_type_params.TypeAt(i);
6602 bound = type_param.bound();
6603 other_bound = other_type_param.bound();
siva 2017/04/20 20:32:08 Should we assert here that the two types are final
regis 2017/04/20 21:18:26 The Equals call should do the right thing in case
6604 if (!bound.Equals(other_bound)) {
6605 return false;
6606 }
6607 }
6608 }
6609 }
6583 // Check the result type. 6610 // Check the result type.
6584 const AbstractType& other_res_type = 6611 const AbstractType& other_res_type =
6585 AbstractType::Handle(other.result_type()); 6612 AbstractType::Handle(zone, other.result_type());
6586 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { 6613 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
6587 const AbstractType& res_type = AbstractType::Handle(result_type()); 6614 const AbstractType& res_type = AbstractType::Handle(zone, result_type());
6588 if (res_type.IsVoidType()) { 6615 if (res_type.IsVoidType()) {
6589 return false; 6616 return false;
6590 } 6617 }
6591 if (test_kind == kIsSubtypeOf) { 6618 if (test_kind == kIsSubtypeOf) {
6592 if (!res_type.IsSubtypeOf(other_res_type, bound_error, NULL, space) && 6619 if (!res_type.IsSubtypeOf(other_res_type, bound_error, NULL, space) &&
6593 !other_res_type.IsSubtypeOf(res_type, bound_error, NULL, space)) { 6620 !other_res_type.IsSubtypeOf(res_type, bound_error, NULL, space)) {
6594 return false; 6621 return false;
6595 } 6622 }
6596 } else { 6623 } else {
6597 ASSERT(test_kind == kIsMoreSpecificThan); 6624 ASSERT(test_kind == kIsMoreSpecificThan);
(...skipping 21 matching lines...) Expand all
6619 // function type, there exists an optional named parameter of this function 6646 // function type, there exists an optional named parameter of this function
6620 // type with an identical name and with a type S that is a either a subtype 6647 // type with an identical name and with a type S that is a either a subtype
6621 // or supertype of T (if test_kind == kIsSubtypeOf) or that is more specific 6648 // or supertype of T (if test_kind == kIsSubtypeOf) or that is more specific
6622 // than T (if test_kind == kIsMoreSpecificThan). 6649 // than T (if test_kind == kIsMoreSpecificThan).
6623 // Note that SetParameterNameAt() guarantees that names are symbols, so we 6650 // Note that SetParameterNameAt() guarantees that names are symbols, so we
6624 // can compare their raw pointers. 6651 // can compare their raw pointers.
6625 const int num_params = num_fixed_params + num_opt_named_params; 6652 const int num_params = num_fixed_params + num_opt_named_params;
6626 const int other_num_params = 6653 const int other_num_params =
6627 other_num_fixed_params + other_num_opt_named_params; 6654 other_num_fixed_params + other_num_opt_named_params;
6628 bool found_param_name; 6655 bool found_param_name;
6629 String& other_param_name = String::Handle(); 6656 String& other_param_name = String::Handle(zone);
6630 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { 6657 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) {
6631 other_param_name = other.ParameterNameAt(i); 6658 other_param_name = other.ParameterNameAt(i);
6632 ASSERT(other_param_name.IsSymbol()); 6659 ASSERT(other_param_name.IsSymbol());
6633 found_param_name = false; 6660 found_param_name = false;
6634 for (intptr_t j = num_fixed_params; j < num_params; j++) { 6661 for (intptr_t j = num_fixed_params; j < num_params; j++) {
6635 ASSERT(String::Handle(ParameterNameAt(j)).IsSymbol()); 6662 ASSERT(String::Handle(zone, ParameterNameAt(j)).IsSymbol());
6636 if (ParameterNameAt(j) == other_param_name.raw()) { 6663 if (ParameterNameAt(j) == other_param_name.raw()) {
6637 found_param_name = true; 6664 found_param_name = true;
6638 if (!TestParameterType(test_kind, j, i, other, bound_error, space)) { 6665 if (!TestParameterType(test_kind, j, i, other, bound_error, space)) {
6639 return false; 6666 return false;
6640 } 6667 }
6641 break; 6668 break;
6642 } 6669 }
6643 } 6670 }
6644 if (!found_param_name) { 6671 if (!found_param_name) {
6645 return false; 6672 return false;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
6755 // Functions other than signature functions have no reason to be allocated 6782 // Functions other than signature functions have no reason to be allocated
6756 // in new space. 6783 // in new space.
6757 ASSERT(space == Heap::kOld); 6784 ASSERT(space == Heap::kOld);
6758 } 6785 }
6759 return result.raw(); 6786 return result.raw();
6760 } 6787 }
6761 6788
6762 6789
6763 RawFunction* Function::Clone(const Class& new_owner) const { 6790 RawFunction* Function::Clone(const Class& new_owner) const {
6764 ASSERT(!IsGenerativeConstructor()); 6791 ASSERT(!IsGenerativeConstructor());
6765 Function& clone = Function::Handle(); 6792 Thread* thread = Thread::Current();
6793 Zone* zone = thread->zone();
6794 Function& clone = Function::Handle(zone);
6766 clone ^= Object::Clone(*this, Heap::kOld); 6795 clone ^= Object::Clone(*this, Heap::kOld);
6767 const Class& origin = Class::Handle(this->origin()); 6796 const Class& origin = Class::Handle(zone, this->origin());
6768 const PatchClass& clone_owner = 6797 const PatchClass& clone_owner =
6769 PatchClass::Handle(PatchClass::New(new_owner, origin)); 6798 PatchClass::Handle(zone, PatchClass::New(new_owner, origin));
6770 clone.set_owner(clone_owner); 6799 clone.set_owner(clone_owner);
6771 clone.ClearICDataArray(); 6800 clone.ClearICDataArray();
6772 clone.ClearCode(); 6801 clone.ClearCode();
6773 clone.set_usage_counter(0); 6802 clone.set_usage_counter(0);
6774 clone.set_deoptimization_counter(0); 6803 clone.set_deoptimization_counter(0);
6775 clone.set_optimized_instruction_count(0); 6804 clone.set_optimized_instruction_count(0);
6776 clone.set_optimized_call_site_count(0); 6805 clone.set_optimized_call_site_count(0);
6777 clone.set_kernel_function(kernel_function()); 6806 clone.set_kernel_function(kernel_function());
6778 // TODO(regis): Clone function type parameters (their bounds may change).
6779 if (new_owner.NumTypeParameters() > 0) { 6807 if (new_owner.NumTypeParameters() > 0) {
6780 // Adjust uninstantiated types to refer to type parameters of the new owner. 6808 // Adjust uninstantiated types to refer to type parameters of the new owner.
6781 AbstractType& type = AbstractType::Handle(clone.result_type()); 6809 const TypeArguments& type_params =
6810 TypeArguments::Handle(zone, type_parameters());
6811 if (!type_params.IsNull()) {
6812 const intptr_t num_type_params = type_params.Length();
6813 const TypeArguments& type_params_clone =
6814 TypeArguments::Handle(zone, TypeArguments::New(num_type_params));
6815 TypeParameter& type_param = TypeParameter::Handle(zone);
6816 for (intptr_t i = 0; i < num_type_params; i++) {
6817 type_param ^= type_params.TypeAt(i);
6818 type_param ^= type_param.CloneUninstantiated(new_owner);
6819 type_params_clone.SetTypeAt(i, type_param);
6820 }
6821 clone.set_type_parameters(type_params_clone);
6822 }
6823 AbstractType& type = AbstractType::Handle(zone, clone.result_type());
6782 type ^= type.CloneUninstantiated(new_owner); 6824 type ^= type.CloneUninstantiated(new_owner);
6783 clone.set_result_type(type); 6825 clone.set_result_type(type);
6784 const intptr_t num_params = clone.NumParameters(); 6826 const intptr_t num_params = clone.NumParameters();
6785 Array& array = Array::Handle(clone.parameter_types()); 6827 Array& array = Array::Handle(zone, clone.parameter_types());
6786 array ^= Object::Clone(array, Heap::kOld); 6828 array ^= Object::Clone(array, Heap::kOld);
6787 clone.set_parameter_types(array); 6829 clone.set_parameter_types(array);
6788 for (intptr_t i = 0; i < num_params; i++) { 6830 for (intptr_t i = 0; i < num_params; i++) {
6789 type = clone.ParameterTypeAt(i); 6831 type = clone.ParameterTypeAt(i);
6790 type ^= type.CloneUninstantiated(new_owner); 6832 type ^= type.CloneUninstantiated(new_owner);
6791 clone.SetParameterTypeAt(i, type); 6833 clone.SetParameterTypeAt(i, type);
6792 } 6834 }
6793 } 6835 }
6794 return clone.raw(); 6836 return clone.raw();
6795 } 6837 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
6853 return result.raw(); 6895 return result.raw();
6854 } 6896 }
6855 6897
6856 RawFunction* Function::ImplicitClosureFunction() const { 6898 RawFunction* Function::ImplicitClosureFunction() const {
6857 // Return the existing implicit closure function if any. 6899 // Return the existing implicit closure function if any.
6858 if (implicit_closure_function() != Function::null()) { 6900 if (implicit_closure_function() != Function::null()) {
6859 return implicit_closure_function(); 6901 return implicit_closure_function();
6860 } 6902 }
6861 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); 6903 ASSERT(!IsSignatureFunction() && !IsClosureFunction());
6862 // Create closure function. 6904 // Create closure function.
6863 const String& closure_name = String::Handle(name()); 6905 const String& closure_name = String::Handle(name());
zra 2017/04/20 19:22:09 Maybe grab the Zone ahead of time for this functio
regis 2017/04/20 20:23:30 Done.
6864 const Function& closure_function = 6906 const Function& closure_function =
6865 Function::Handle(NewClosureFunction(closure_name, *this, token_pos())); 6907 Function::Handle(NewClosureFunction(closure_name, *this, token_pos()));
6866 6908
6867 // Set closure function's context scope. 6909 // Set closure function's context scope.
6868 if (is_static()) { 6910 if (is_static()) {
6869 closure_function.set_context_scope(Object::empty_context_scope()); 6911 closure_function.set_context_scope(Object::empty_context_scope());
6870 } else { 6912 } else {
6871 const ContextScope& context_scope = 6913 const ContextScope& context_scope =
6872 ContextScope::Handle(LocalScope::CreateImplicitClosureScope(*this)); 6914 ContextScope::Handle(LocalScope::CreateImplicitClosureScope(*this));
6873 closure_function.set_context_scope(context_scope); 6915 closure_function.set_context_scope(context_scope);
6874 } 6916 }
6875 6917
6918 // Set closure function's type parameters.
6919 closure_function.set_type_parameters(
6920 TypeArguments::Handle(type_parameters()));
6921
6876 // Set closure function's result type to this result type. 6922 // Set closure function's result type to this result type.
6877 closure_function.set_result_type(AbstractType::Handle(result_type())); 6923 closure_function.set_result_type(AbstractType::Handle(result_type()));
6878 6924
6879 // Set closure function's end token to this end token. 6925 // Set closure function's end token to this end token.
6880 closure_function.set_end_token_pos(end_token_pos()); 6926 closure_function.set_end_token_pos(end_token_pos());
6881 6927
6882 // The closurized method stub just calls into the original method and should 6928 // The closurized method stub just calls into the original method and should
6883 // therefore be skipped by the debugger and in stack traces. 6929 // therefore be skipped by the debugger and in stack traces.
6884 closure_function.set_is_debuggable(false); 6930 closure_function.set_is_debuggable(false);
6885 closure_function.set_is_visible(false); 6931 closure_function.set_is_visible(false);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
7058 result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1); 7104 result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1);
7059 ClosureData::Cast(obj).set_hash(result); 7105 ClosureData::Cast(obj).set_hash(result);
7060 return Smi::New(result); 7106 return Smi::New(result);
7061 } 7107 }
7062 7108
7063 7109
7064 RawString* Function::BuildSignature(NameVisibility name_visibility) const { 7110 RawString* Function::BuildSignature(NameVisibility name_visibility) const {
7065 Thread* thread = Thread::Current(); 7111 Thread* thread = Thread::Current();
7066 Zone* zone = thread->zone(); 7112 Zone* zone = thread->zone();
7067 GrowableHandlePtrArray<const String> pieces(zone, 4); 7113 GrowableHandlePtrArray<const String> pieces(zone, 4);
7114 String& name = String::Handle(zone);
7115 if (FLAG_reify_generic_functions) {
7116 const TypeArguments& type_params =
7117 TypeArguments::Handle(zone, type_parameters());
7118 if (!type_params.IsNull()) {
7119 const intptr_t num_type_params = type_params.Length();
7120 TypeParameter& type_param = TypeParameter::Handle(zone);
7121 AbstractType& bound = AbstractType::Handle(zone);
7122 pieces.Add(Symbols::LAngleBracket());
7123 for (intptr_t i = 0; i < num_type_params; i++) {
7124 type_param ^= type_params.TypeAt(i);
7125 name = type_param.name();
7126 pieces.Add(name);
7127 bound = type_param.bound();
7128 if (!bound.IsNull() && !bound.IsObjectType()) {
7129 pieces.Add(Symbols::SpaceExtendsSpace());
7130 name = bound.BuildName(name_visibility);
7131 pieces.Add(name);
7132 }
7133 if (i < num_type_params - 1) {
7134 pieces.Add(Symbols::CommaSpace());
7135 }
7136 }
7137 pieces.Add(Symbols::RAngleBracket());
siva 2017/04/20 20:32:08 Do we still want '<>' if num_type_params is 0? or
regis 2017/04/20 21:18:26 Yes, we should never see an empty array. I added a
7138 }
7139 }
7068 pieces.Add(Symbols::LParen()); 7140 pieces.Add(Symbols::LParen());
7069 BuildSignatureParameters(thread, zone, name_visibility, &pieces); 7141 BuildSignatureParameters(thread, zone, name_visibility, &pieces);
7070 pieces.Add(Symbols::RParenArrow()); 7142 pieces.Add(Symbols::RParenArrow());
7071 const AbstractType& res_type = AbstractType::Handle(zone, result_type()); 7143 const AbstractType& res_type = AbstractType::Handle(zone, result_type());
7072 const String& name = 7144 name = res_type.BuildName(name_visibility);
7073 String::Handle(zone, res_type.BuildName(name_visibility));
7074 pieces.Add(name); 7145 pieces.Add(name);
7075 return Symbols::FromConcatAll(thread, pieces); 7146 return Symbols::FromConcatAll(thread, pieces);
7076 } 7147 }
7077 7148
7078 7149
7079 bool Function::HasInstantiatedSignature(Genericity genericity, 7150 bool Function::HasInstantiatedSignature(Genericity genericity,
7080 TrailPtr trail) const { 7151 TrailPtr trail) const {
7081 AbstractType& type = AbstractType::Handle(result_type()); 7152 AbstractType& type = AbstractType::Handle(result_type());
7082 if (!type.IsInstantiated(genericity, trail)) { 7153 if (!type.IsInstantiated(genericity, trail)) {
7083 return false; 7154 return false;
(...skipping 8723 matching lines...) Expand 10 before | Expand all | Expand 10 after
15807 // Check if this instance understands a call() method of a compatible type. 15878 // Check if this instance understands a call() method of a compatible type.
15808 Function& sig_fun = 15879 Function& sig_fun =
15809 Function::Handle(zone, cls.LookupCallFunctionForTypeTest()); 15880 Function::Handle(zone, cls.LookupCallFunctionForTypeTest());
15810 if (!sig_fun.IsNull()) { 15881 if (!sig_fun.IsNull()) {
15811 if (other_is_dart_function) { 15882 if (other_is_dart_function) {
15812 return true; 15883 return true;
15813 } 15884 }
15814 if (!sig_fun.HasInstantiatedSignature()) { 15885 if (!sig_fun.HasInstantiatedSignature()) {
15815 const TypeArguments& function_type_arguments = 15886 const TypeArguments& function_type_arguments =
15816 TypeArguments::Handle(zone, sig_fun.type_parameters()); 15887 TypeArguments::Handle(zone, sig_fun.type_parameters());
15817 // TODO(regis): Pass the closure context to InstantiateSignatureFrom().
15818 // No bound error possible, since the instance exists. 15888 // No bound error possible, since the instance exists.
15819 sig_fun = sig_fun.InstantiateSignatureFrom( 15889 sig_fun = sig_fun.InstantiateSignatureFrom(
15820 type_arguments, function_type_arguments, Heap::kOld); 15890 type_arguments, function_type_arguments, Heap::kOld);
15821 } 15891 }
15822 const Function& other_signature = 15892 const Function& other_signature =
15823 Function::Handle(zone, Type::Cast(instantiated_other).signature()); 15893 Function::Handle(zone, Type::Cast(instantiated_other).signature());
15824 if (sig_fun.IsSubtypeOf(other_signature, bound_error, Heap::kOld)) { 15894 if (sig_fun.IsSubtypeOf(other_signature, bound_error, Heap::kOld)) {
15825 return true; 15895 return true;
15826 } 15896 }
15827 } 15897 }
(...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after
17116 ASSERT(Type::Cast(other).IsFunctionType()); 17186 ASSERT(Type::Cast(other).IsFunctionType());
17117 // Equal function types must have equal signature types and equal optional 17187 // Equal function types must have equal signature types and equal optional
17118 // named arguments. 17188 // named arguments.
17119 if (signature() == other_type.signature()) { 17189 if (signature() == other_type.signature()) {
17120 return true; 17190 return true;
17121 } 17191 }
17122 const Function& sig_fun = Function::Handle(zone, signature()); 17192 const Function& sig_fun = Function::Handle(zone, signature());
17123 const Function& other_sig_fun = 17193 const Function& other_sig_fun =
17124 Function::Handle(zone, other_type.signature()); 17194 Function::Handle(zone, other_type.signature());
17125 17195
17196 if (FLAG_reify_generic_functions) {
17197 // Compare function type parameters and their bounds.
17198 const intptr_t num_type_params = sig_fun.NumTypeParameters(thread);
17199 if (num_type_params != other_sig_fun.NumTypeParameters(thread)) {
17200 return false;
17201 }
17202 if (num_type_params > 0) {
17203 const TypeArguments& type_params =
17204 TypeArguments::Handle(zone, sig_fun.type_parameters());
17205 ASSERT(!type_params.IsNull());
17206 const TypeArguments& other_type_params =
17207 TypeArguments::Handle(zone, other_sig_fun.type_parameters());
17208 ASSERT(!other_type_params.IsNull());
17209 TypeParameter& type_param = TypeParameter::Handle(zone);
17210 TypeParameter& other_type_param = TypeParameter::Handle(zone);
17211 AbstractType& bound = AbstractType::Handle(zone);
17212 AbstractType& other_bound = AbstractType::Handle(zone);
17213 for (intptr_t i = 0; i < num_type_params; i++) {
17214 type_param ^= type_params.TypeAt(i);
17215 other_type_param ^= other_type_params.TypeAt(i);
17216 bound = type_param.bound();
17217 other_bound = other_type_param.bound();
17218 if (!bound.Equals(other_bound)) {
17219 return false;
17220 }
17221 }
17222 }
siva 2017/04/20 20:32:08 This code here is very similar to the one in Funct
regis 2017/04/20 21:18:26 That was bugging me too, and then I forgot :-) I a
17223 }
17224
17126 // Compare number of function parameters. 17225 // Compare number of function parameters.
17127 const intptr_t num_fixed_params = sig_fun.num_fixed_parameters(); 17226 const intptr_t num_fixed_params = sig_fun.num_fixed_parameters();
17128 const intptr_t other_num_fixed_params = other_sig_fun.num_fixed_parameters(); 17227 const intptr_t other_num_fixed_params = other_sig_fun.num_fixed_parameters();
17129 if (num_fixed_params != other_num_fixed_params) { 17228 if (num_fixed_params != other_num_fixed_params) {
17130 return false; 17229 return false;
17131 } 17230 }
17132 const intptr_t num_opt_pos_params = sig_fun.NumOptionalPositionalParameters(); 17231 const intptr_t num_opt_pos_params = sig_fun.NumOptionalPositionalParameters();
17133 const intptr_t other_num_opt_pos_params = 17232 const intptr_t other_num_opt_pos_params =
17134 other_sig_fun.NumOptionalPositionalParameters(); 17233 other_sig_fun.NumOptionalPositionalParameters();
17135 if (num_opt_pos_params != other_num_opt_pos_params) { 17234 if (num_opt_pos_params != other_num_opt_pos_params) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
17204 if (IsMalbounded()) { 17303 if (IsMalbounded()) {
17205 const LanguageError& bound_error = LanguageError::Handle(zone, error()); 17304 const LanguageError& bound_error = LanguageError::Handle(zone, error());
17206 clone.set_error(bound_error); 17305 clone.set_error(bound_error);
17207 } 17306 }
17208 // Clone the signature if this type represents a function type. 17307 // Clone the signature if this type represents a function type.
17209 Function& fun = Function::Handle(zone, signature()); 17308 Function& fun = Function::Handle(zone, signature());
17210 if (!fun.IsNull()) { 17309 if (!fun.IsNull()) {
17211 const Class& owner = Class::Handle(zone, fun.Owner()); 17310 const Class& owner = Class::Handle(zone, fun.Owner());
17212 Function& fun_clone = Function::Handle( 17311 Function& fun_clone = Function::Handle(
17213 zone, Function::NewSignatureFunction(owner, TokenPosition::kNoSource)); 17312 zone, Function::NewSignatureFunction(owner, TokenPosition::kNoSource));
17214 // TODO(regis): Handle cloning of a generic function type. 17313 const TypeArguments& type_params =
17314 TypeArguments::Handle(zone, fun.type_parameters());
17315 if (!type_params.IsNull()) {
17316 const intptr_t num_type_params = type_params.Length();
17317 const TypeArguments& type_params_clone =
17318 TypeArguments::Handle(zone, TypeArguments::New(num_type_params));
17319 TypeParameter& type_param = TypeParameter::Handle(zone);
17320 for (intptr_t i = 0; i < num_type_params; i++) {
17321 type_param ^= type_params.TypeAt(i);
17322 type_param ^= type_param.CloneUnfinalized();
17323 type_params_clone.SetTypeAt(i, type_param);
17324 }
17325 fun_clone.set_type_parameters(type_params_clone);
17326 }
siva 2017/04/20 20:32:08 ditto comment about this matching up with the one
regis 2017/04/20 21:18:25 This one cannot easily be factored out. One is cal
17215 AbstractType& type = AbstractType::Handle(zone, fun.result_type()); 17327 AbstractType& type = AbstractType::Handle(zone, fun.result_type());
17216 type = type.CloneUnfinalized(); 17328 type = type.CloneUnfinalized();
17217 fun_clone.set_result_type(type); 17329 fun_clone.set_result_type(type);
17218 const intptr_t num_params = fun.NumParameters(); 17330 const intptr_t num_params = fun.NumParameters();
17219 fun_clone.set_num_fixed_parameters(fun.num_fixed_parameters()); 17331 fun_clone.set_num_fixed_parameters(fun.num_fixed_parameters());
17220 fun_clone.SetNumOptionalParameters(fun.NumOptionalParameters(), 17332 fun_clone.SetNumOptionalParameters(fun.NumOptionalParameters(),
17221 fun.HasOptionalPositionalParameters()); 17333 fun.HasOptionalPositionalParameters());
17222 fun_clone.set_parameter_types( 17334 fun_clone.set_parameter_types(
17223 Array::Handle(Array::New(num_params, Heap::kOld))); 17335 Array::Handle(Array::New(num_params, Heap::kOld)));
17224 for (intptr_t i = 0; i < num_params; i++) { 17336 for (intptr_t i = 0; i < num_params; i++) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
17260 } 17372 }
17261 // Clone the signature if this type represents a function type. 17373 // Clone the signature if this type represents a function type.
17262 const Function& fun = Function::Handle(zone, signature()); 17374 const Function& fun = Function::Handle(zone, signature());
17263 if (!fun.IsNull()) { 17375 if (!fun.IsNull()) {
17264 ASSERT(type_cls.IsTypedefClass() || type_cls.IsClosureClass()); 17376 ASSERT(type_cls.IsTypedefClass() || type_cls.IsClosureClass());
17265 // If the scope class is not a typedef and if it is generic, it must be the 17377 // If the scope class is not a typedef and if it is generic, it must be the
17266 // mixin class, set it to the new owner. 17378 // mixin class, set it to the new owner.
17267 Function& fun_clone = Function::Handle( 17379 Function& fun_clone = Function::Handle(
17268 zone, 17380 zone,
17269 Function::NewSignatureFunction(new_owner, TokenPosition::kNoSource)); 17381 Function::NewSignatureFunction(new_owner, TokenPosition::kNoSource));
17382 const TypeArguments& type_params =
17383 TypeArguments::Handle(zone, fun.type_parameters());
17384 if (!type_params.IsNull()) {
17385 const intptr_t num_type_params = type_params.Length();
17386 const TypeArguments& type_params_clone =
17387 TypeArguments::Handle(zone, TypeArguments::New(num_type_params));
17388 TypeParameter& type_param = TypeParameter::Handle(zone);
17389 for (intptr_t i = 0; i < num_type_params; i++) {
17390 type_param ^= type_params.TypeAt(i);
17391 type_param ^= type_param.CloneUninstantiated(new_owner, trail);
17392 type_params_clone.SetTypeAt(i, type_param);
17393 }
17394 fun_clone.set_type_parameters(type_params_clone);
17395 }
17270 AbstractType& type = AbstractType::Handle(zone, fun.result_type()); 17396 AbstractType& type = AbstractType::Handle(zone, fun.result_type());
17271 type = type.CloneUninstantiated(new_owner, trail); 17397 type = type.CloneUninstantiated(new_owner, trail);
17272 fun_clone.set_result_type(type); 17398 fun_clone.set_result_type(type);
17273 const intptr_t num_params = fun.NumParameters(); 17399 const intptr_t num_params = fun.NumParameters();
17274 fun_clone.set_num_fixed_parameters(fun.num_fixed_parameters()); 17400 fun_clone.set_num_fixed_parameters(fun.num_fixed_parameters());
17275 fun_clone.SetNumOptionalParameters(fun.NumOptionalParameters(), 17401 fun_clone.SetNumOptionalParameters(fun.NumOptionalParameters(),
17276 fun.HasOptionalPositionalParameters()); 17402 fun.HasOptionalPositionalParameters());
17277 fun_clone.set_parameter_types( 17403 fun_clone.set_parameter_types(
17278 Array::Handle(Array::New(num_params, Heap::kOld))); 17404 Array::Handle(Array::New(num_params, Heap::kOld)));
17279 for (intptr_t i = 0; i < num_params; i++) { 17405 for (intptr_t i = 0; i < num_params; i++) {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
17386 ASSERT(type_args.IsNull() || type_args.IsOld()); 17512 ASSERT(type_args.IsNull() || type_args.IsOld());
17387 17513
17388 // In case of a function type, replace the actual function by a signature 17514 // In case of a function type, replace the actual function by a signature
17389 // function. 17515 // function.
17390 if (IsFunctionType()) { 17516 if (IsFunctionType()) {
17391 const Function& fun = Function::Handle(zone, signature()); 17517 const Function& fun = Function::Handle(zone, signature());
17392 if (!fun.IsSignatureFunction()) { 17518 if (!fun.IsSignatureFunction()) {
17393 Function& sig_fun = Function::Handle( 17519 Function& sig_fun = Function::Handle(
17394 zone, 17520 zone,
17395 Function::NewSignatureFunction(cls, TokenPosition::kNoSource)); 17521 Function::NewSignatureFunction(cls, TokenPosition::kNoSource));
17522 sig_fun.set_type_parameters(
17523 TypeArguments::Handle(zone, fun.type_parameters()));
17396 type = fun.result_type(); 17524 type = fun.result_type();
17397 type = type.Canonicalize(trail); 17525 type = type.Canonicalize(trail);
17398 sig_fun.set_result_type(type); 17526 sig_fun.set_result_type(type);
17399 const intptr_t num_params = fun.NumParameters(); 17527 const intptr_t num_params = fun.NumParameters();
17400 sig_fun.set_num_fixed_parameters(fun.num_fixed_parameters()); 17528 sig_fun.set_num_fixed_parameters(fun.num_fixed_parameters());
17401 sig_fun.SetNumOptionalParameters(fun.NumOptionalParameters(), 17529 sig_fun.SetNumOptionalParameters(fun.NumOptionalParameters(),
17402 fun.HasOptionalPositionalParameters()); 17530 fun.HasOptionalPositionalParameters());
17403 sig_fun.set_parameter_types( 17531 sig_fun.set_parameter_types(
17404 Array::Handle(Array::New(num_params, Heap::kOld))); 17532 Array::Handle(Array::New(num_params, Heap::kOld)));
17405 for (intptr_t i = 0; i < num_params; i++) { 17533 for (intptr_t i = 0; i < num_params; i++) {
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
18013 return TypeParameter::New(Class::Handle(parameterized_class()), 18141 return TypeParameter::New(Class::Handle(parameterized_class()),
18014 Function::Handle(parameterized_function()), index(), 18142 Function::Handle(parameterized_function()), index(),
18015 String::Handle(name()), 18143 String::Handle(name()),
18016 AbstractType::Handle(bound()), token_pos()); 18144 AbstractType::Handle(bound()), token_pos());
18017 } 18145 }
18018 18146
18019 18147
18020 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, 18148 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner,
18021 TrailPtr trail) const { 18149 TrailPtr trail) const {
18022 ASSERT(IsFinalized()); 18150 ASSERT(IsFinalized());
18023 TypeParameter& clone = TypeParameter::Handle(); 18151 TypeParameter& clone = TypeParameter::Handle();
zra 2017/04/20 19:22:09 ditto
regis 2017/04/20 20:23:30 Done.
18024 clone ^= OnlyBuddyInTrail(trail); 18152 clone ^= OnlyBuddyInTrail(trail);
18025 if (!clone.IsNull()) { 18153 if (!clone.IsNull()) {
18026 return clone.raw(); 18154 return clone.raw();
18027 } 18155 }
18028 const Class& old_owner = Class::Handle(parameterized_class()); 18156 intptr_t new_index = index();
18029 if (old_owner.IsNull()) { 18157 AbstractType& upper_bound = AbstractType::Handle(bound());
18158 const Function& fun = Function::Handle(parameterized_function());
18159 Class& cls = Class::Handle(parameterized_class());
18160 if (!cls.IsNull()) {
18161 ASSERT(fun.IsNull());
18162 new_index += new_owner.NumTypeArguments() - cls.NumTypeArguments();
18163 cls = new_owner.raw();
18164 } else {
18030 ASSERT(IsFunctionTypeParameter()); 18165 ASSERT(IsFunctionTypeParameter());
18031 // Function type parameters do not need cloning. 18166 // Only the bounds of function type parameters need cloning.
18032 return raw();
18033 } 18167 }
18034 const intptr_t new_index = 18168 clone = TypeParameter::New(cls, fun, new_index, String::Handle(name()),
18035 index() + new_owner.NumTypeArguments() - old_owner.NumTypeArguments();
18036 AbstractType& upper_bound = AbstractType::Handle(bound());
18037 ASSERT(parameterized_function() == Function::null());
18038 clone = TypeParameter::New(new_owner, Function::Handle(), new_index,
18039 String::Handle(name()),
18040 upper_bound, // Not cloned yet. 18169 upper_bound, // Not cloned yet.
18041 token_pos()); 18170 token_pos());
18042 clone.SetIsFinalized(); 18171 clone.SetIsFinalized();
18043 AddOnlyBuddyToTrail(&trail, clone); 18172 AddOnlyBuddyToTrail(&trail, clone);
18044 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); 18173 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail);
18045 clone.set_bound(upper_bound); 18174 clone.set_bound(upper_bound);
18046 return clone.raw(); 18175 return clone.raw();
18047 } 18176 }
18048 18177
18049 18178
(...skipping 5118 matching lines...) Expand 10 before | Expand all | Expand 10 after
23168 return UserTag::null(); 23297 return UserTag::null();
23169 } 23298 }
23170 23299
23171 23300
23172 const char* UserTag::ToCString() const { 23301 const char* UserTag::ToCString() const {
23173 const String& tag_label = String::Handle(label()); 23302 const String& tag_label = String::Handle(label());
23174 return tag_label.ToCString(); 23303 return tag_label.ToCString();
23175 } 23304 }
23176 23305
23177 } // namespace dart 23306 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698