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

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

Issue 10579033: Fix type test elimination of function types using static type propagation in (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/function_type_test.dart » ('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 "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after
1783 other_type_arguments, 1783 other_type_arguments,
1784 len, 1784 len,
1785 malformed_error); 1785 malformed_error);
1786 } 1786 }
1787 // TODO(regis): Check for interface type S implementing method call() of 1787 // TODO(regis): Check for interface type S implementing method call() of
1788 // function type T. 1788 // function type T.
1789 // Check for two function types. 1789 // Check for two function types.
1790 if (IsSignatureClass() && other.IsSignatureClass()) { 1790 if (IsSignatureClass() && other.IsSignatureClass()) {
1791 const Function& fun = Function::Handle(signature_function()); 1791 const Function& fun = Function::Handle(signature_function());
1792 const Function& other_fun = Function::Handle(other.signature_function()); 1792 const Function& other_fun = Function::Handle(other.signature_function());
1793 return fun.IsSubtypeOf(type_arguments, 1793 return fun.TypeTest(test_kind,
1794 other_fun, 1794 type_arguments,
1795 other_type_arguments, 1795 other_fun,
1796 malformed_error); 1796 other_type_arguments,
1797 malformed_error);
1797 } 1798 }
1798 // Check for 'direct super type' in the case of an interface 1799 // Check for 'direct super type' in the case of an interface
1799 // (i.e. other.is_interface()) or implicit interface (i.e. 1800 // (i.e. other.is_interface()) or implicit interface (i.e.
1800 // !other.is_interface()) and check for transitivity at the same time. 1801 // !other.is_interface()) and check for transitivity at the same time.
1801 Array& interfaces = Array::Handle(this->interfaces()); 1802 Array& interfaces = Array::Handle(this->interfaces());
1802 AbstractType& interface = AbstractType::Handle(); 1803 AbstractType& interface = AbstractType::Handle();
1803 Class& interface_class = Class::Handle(); 1804 Class& interface_class = Class::Handle();
1804 AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle(); 1805 AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle();
1805 for (intptr_t i = 0; i < interfaces.Length(); i++) { 1806 for (intptr_t i = 0; i < interfaces.Length(); i++) {
1806 interface ^= interfaces.At(i); 1807 interface ^= interfaces.At(i);
(...skipping 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after
3763 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { 3764 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) {
3764 const String& other_param_name = String::Handle(other.ParameterNameAt(i)); 3765 const String& other_param_name = String::Handle(other.ParameterNameAt(i));
3765 if (ParameterNameAt(i) != other_param_name.raw()) { 3766 if (ParameterNameAt(i) != other_param_name.raw()) {
3766 return false; 3767 return false;
3767 } 3768 }
3768 } 3769 }
3769 return true; 3770 return true;
3770 } 3771 }
3771 3772
3772 3773
3774 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter
3775 // of this function is a subtype or a supertype of the type of the corresponding
3776 // parameter of the other function.
3777 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified
3778 // parameter of this function is more specific than the type of the
3779 // corresponding parameter of the other function.
3780 // Note that we do not apply contravariance of parameter types, but covariance
3781 // of both parameter types and result type.
3773 bool Function::TestParameterType( 3782 bool Function::TestParameterType(
3783 TypeTestKind test_kind,
3774 intptr_t parameter_position, 3784 intptr_t parameter_position,
3775 const AbstractTypeArguments& type_arguments, 3785 const AbstractTypeArguments& type_arguments,
3776 const Function& other, 3786 const Function& other,
3777 const AbstractTypeArguments& other_type_arguments, 3787 const AbstractTypeArguments& other_type_arguments,
3778 Error* malformed_error) const { 3788 Error* malformed_error) const {
3779 AbstractType& param_type =
3780 AbstractType::Handle(ParameterTypeAt(parameter_position));
3781 if (!param_type.IsInstantiated()) {
3782 param_type = param_type.InstantiateFrom(type_arguments);
3783 }
3784 if (param_type.IsDynamicType()) {
3785 return true;
3786 }
3787 AbstractType& other_param_type = 3789 AbstractType& other_param_type =
3788 AbstractType::Handle(other.ParameterTypeAt(parameter_position)); 3790 AbstractType::Handle(other.ParameterTypeAt(parameter_position));
3789 if (!other_param_type.IsInstantiated()) { 3791 if (!other_param_type.IsInstantiated()) {
3790 other_param_type = other_param_type.InstantiateFrom(other_type_arguments); 3792 other_param_type = other_param_type.InstantiateFrom(other_type_arguments);
3791 } 3793 }
3792 if (other_param_type.IsDynamicType()) { 3794 if (other_param_type.IsDynamicType()) {
3793 return true; 3795 return true;
3794 } 3796 }
3795 if (!param_type.IsSubtypeOf(other_param_type, malformed_error) && 3797 AbstractType& param_type =
3796 !other_param_type.IsSubtypeOf(param_type, malformed_error)) { 3798 AbstractType::Handle(ParameterTypeAt(parameter_position));
3797 return false; 3799 if (!param_type.IsInstantiated()) {
3800 param_type = param_type.InstantiateFrom(type_arguments);
3801 }
3802 if (param_type.IsDynamicType()) {
3803 return test_kind == kIsSubtypeOf;
3804 }
3805 if (test_kind == kIsSubtypeOf) {
3806 if (!param_type.IsSubtypeOf(other_param_type, malformed_error) &&
3807 !other_param_type.IsSubtypeOf(param_type, malformed_error)) {
3808 return false;
3809 }
3810 } else {
3811 ASSERT(test_kind == kIsMoreSpecificThan);
3812 if (!param_type.IsMoreSpecificThan(other_param_type, malformed_error)) {
3813 return false;
3814 }
3798 } 3815 }
3799 return true; 3816 return true;
3800 } 3817 }
3801 3818
3802 3819
3803 bool Function::IsSubtypeOf( 3820 bool Function::TypeTest(TypeTestKind test_kind,
3804 const AbstractTypeArguments& type_arguments, 3821 const AbstractTypeArguments& type_arguments,
3805 const Function& other, 3822 const Function& other,
3806 const AbstractTypeArguments& other_type_arguments, 3823 const AbstractTypeArguments& other_type_arguments,
3807 Error* malformed_error) const { 3824 Error* malformed_error) const {
3808 const intptr_t num_fixed_params = num_fixed_parameters(); 3825 const intptr_t num_fixed_params = num_fixed_parameters();
3809 const intptr_t num_opt_params = num_optional_parameters(); 3826 const intptr_t num_opt_params = num_optional_parameters();
3810 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); 3827 const intptr_t other_num_fixed_params = other.num_fixed_parameters();
3811 const intptr_t other_num_opt_params = other.num_optional_parameters(); 3828 const intptr_t other_num_opt_params = other.num_optional_parameters();
3812 if ((num_fixed_params != other_num_fixed_params) || 3829 if ((num_fixed_params != other_num_fixed_params) ||
3813 (num_opt_params < other_num_opt_params)) { 3830 (num_opt_params < other_num_opt_params)) {
3814 return false; 3831 return false;
3815 } 3832 }
3816 // Check the result type. 3833 // Check the result type.
3817 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); 3834 AbstractType& other_res_type = AbstractType::Handle(other.result_type());
3818 if (!other_res_type.IsInstantiated()) { 3835 if (!other_res_type.IsInstantiated()) {
3819 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); 3836 other_res_type = other_res_type.InstantiateFrom(other_type_arguments);
3820 } 3837 }
3821 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { 3838 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
3822 AbstractType& res_type = AbstractType::Handle(result_type()); 3839 AbstractType& res_type = AbstractType::Handle(result_type());
3823 if (!res_type.IsInstantiated()) { 3840 if (!res_type.IsInstantiated()) {
3824 res_type = res_type.InstantiateFrom(type_arguments); 3841 res_type = res_type.InstantiateFrom(type_arguments);
3825 } 3842 }
3826 if (!res_type.IsDynamicType() && 3843 if (res_type.IsVoidType()) {
3827 (res_type.IsVoidType() ||
3828 !(res_type.IsSubtypeOf(other_res_type, malformed_error) ||
3829 other_res_type.IsSubtypeOf(res_type, malformed_error)))) {
3830 return false; 3844 return false;
3831 } 3845 }
3846 if (test_kind == kIsSubtypeOf) {
3847 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) &&
3848 !other_res_type.IsSubtypeOf(res_type, malformed_error)) {
3849 return false;
3850 }
3851 } else {
3852 ASSERT(test_kind == kIsMoreSpecificThan);
3853 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) {
3854 return false;
3855 }
3856 }
3832 } 3857 }
3833 // Check the types of fixed parameters. 3858 // Check the types of fixed parameters.
3834 for (intptr_t i = 0; i < num_fixed_params; i++) { 3859 for (intptr_t i = 0; i < num_fixed_params; i++) {
3835 if (!TestParameterType(i, type_arguments, other, other_type_arguments, 3860 if (!TestParameterType(test_kind,
3861 i, type_arguments, other, other_type_arguments,
3836 malformed_error)) { 3862 malformed_error)) {
3837 return false; 3863 return false;
3838 } 3864 }
3839 } 3865 }
3840 // Check the names and types of optional parameters. 3866 // Check the names and types of optional parameters.
3841 // Check that for each optional named parameter of type T of the other 3867 // Check that for each optional named parameter of type T of the other
3842 // function type, there is a corresponding optional named parameter of this 3868 // function type, there is a corresponding optional named parameter of this
3843 // function at the same position with an identical name and with a type S 3869 // function at the same position with an identical name and with a type S
3844 // that is a subtype or supertype of T. 3870 // that is a either a subtype or supertype of T (if test_kind == kIsSubtypeOf)
3871 // or that is more specific than T (if test_kind == kIsMoreSpecificThan).
3845 // Note that SetParameterNameAt() guarantees that names are symbols, so we 3872 // Note that SetParameterNameAt() guarantees that names are symbols, so we
3846 // can compare their raw pointers. 3873 // can compare their raw pointers.
3847 const intptr_t other_num_params = 3874 const intptr_t other_num_params =
3848 other_num_fixed_params + other_num_opt_params; 3875 other_num_fixed_params + other_num_opt_params;
3849 String& other_param_name = String::Handle(); 3876 String& other_param_name = String::Handle();
3850 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { 3877 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) {
3851 other_param_name = other.ParameterNameAt(i); 3878 other_param_name = other.ParameterNameAt(i);
3852 if ((ParameterNameAt(i) != other_param_name.raw()) || 3879 if ((ParameterNameAt(i) != other_param_name.raw()) ||
3853 !TestParameterType(i, type_arguments, other, other_type_arguments, 3880 !TestParameterType(test_kind,
3881 i, type_arguments, other, other_type_arguments,
3854 malformed_error)) { 3882 malformed_error)) {
3855 return false; 3883 return false;
3856 } 3884 }
3857 } 3885 }
3858 return true; 3886 return true;
3859 } 3887 }
3860 3888
3861 3889
3862 bool Function::IsImplicitClosureFunction() const { 3890 bool Function::IsImplicitClosureFunction() const {
3863 if (!IsClosureFunction()) { 3891 if (!IsClosureFunction()) {
(...skipping 6314 matching lines...) Expand 10 before | Expand all | Expand 10 after
10178 const String& str = String::Handle(pattern()); 10206 const String& str = String::Handle(pattern());
10179 const char* format = "JSRegExp: pattern=%s flags=%s"; 10207 const char* format = "JSRegExp: pattern=%s flags=%s";
10180 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 10208 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
10181 char* chars = reinterpret_cast<char*>( 10209 char* chars = reinterpret_cast<char*>(
10182 Isolate::Current()->current_zone()->Allocate(len + 1)); 10210 Isolate::Current()->current_zone()->Allocate(len + 1));
10183 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 10211 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
10184 return chars; 10212 return chars;
10185 } 10213 }
10186 10214
10187 } // namespace dart 10215 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/function_type_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698