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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/function_type_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 8880)
+++ runtime/vm/object.cc (working copy)
@@ -1790,10 +1790,11 @@
if (IsSignatureClass() && other.IsSignatureClass()) {
const Function& fun = Function::Handle(signature_function());
const Function& other_fun = Function::Handle(other.signature_function());
- return fun.IsSubtypeOf(type_arguments,
- other_fun,
- other_type_arguments,
- malformed_error);
+ return fun.TypeTest(test_kind,
+ type_arguments,
+ other_fun,
+ other_type_arguments,
+ malformed_error);
}
// Check for 'direct super type' in the case of an interface
// (i.e. other.is_interface()) or implicit interface (i.e.
@@ -3770,20 +3771,21 @@
}
+// If test_kind == kIsSubtypeOf, checks if the type of the specified parameter
+// of this function is a subtype or a supertype of the type of the corresponding
+// parameter of the other function.
+// If test_kind == kIsMoreSpecificThan, checks if the type of the specified
+// parameter of this function is more specific than the type of the
+// corresponding parameter of the other function.
+// Note that we do not apply contravariance of parameter types, but covariance
+// of both parameter types and result type.
bool Function::TestParameterType(
+ TypeTestKind test_kind,
intptr_t parameter_position,
const AbstractTypeArguments& type_arguments,
const Function& other,
const AbstractTypeArguments& other_type_arguments,
Error* malformed_error) const {
- AbstractType& param_type =
- AbstractType::Handle(ParameterTypeAt(parameter_position));
- if (!param_type.IsInstantiated()) {
- param_type = param_type.InstantiateFrom(type_arguments);
- }
- if (param_type.IsDynamicType()) {
- return true;
- }
AbstractType& other_param_type =
AbstractType::Handle(other.ParameterTypeAt(parameter_position));
if (!other_param_type.IsInstantiated()) {
@@ -3792,19 +3794,34 @@
if (other_param_type.IsDynamicType()) {
return true;
}
- if (!param_type.IsSubtypeOf(other_param_type, malformed_error) &&
- !other_param_type.IsSubtypeOf(param_type, malformed_error)) {
- return false;
+ AbstractType& param_type =
+ AbstractType::Handle(ParameterTypeAt(parameter_position));
+ if (!param_type.IsInstantiated()) {
+ param_type = param_type.InstantiateFrom(type_arguments);
}
+ if (param_type.IsDynamicType()) {
+ return test_kind == kIsSubtypeOf;
+ }
+ if (test_kind == kIsSubtypeOf) {
+ if (!param_type.IsSubtypeOf(other_param_type, malformed_error) &&
+ !other_param_type.IsSubtypeOf(param_type, malformed_error)) {
+ return false;
+ }
+ } else {
+ ASSERT(test_kind == kIsMoreSpecificThan);
+ if (!param_type.IsMoreSpecificThan(other_param_type, malformed_error)) {
+ return false;
+ }
+ }
return true;
}
-bool Function::IsSubtypeOf(
- const AbstractTypeArguments& type_arguments,
- const Function& other,
- const AbstractTypeArguments& other_type_arguments,
- Error* malformed_error) const {
+bool Function::TypeTest(TypeTestKind test_kind,
+ const AbstractTypeArguments& type_arguments,
+ const Function& other,
+ const AbstractTypeArguments& other_type_arguments,
+ Error* malformed_error) const {
const intptr_t num_fixed_params = num_fixed_parameters();
const intptr_t num_opt_params = num_optional_parameters();
const intptr_t other_num_fixed_params = other.num_fixed_parameters();
@@ -3823,16 +3840,25 @@
if (!res_type.IsInstantiated()) {
res_type = res_type.InstantiateFrom(type_arguments);
}
- if (!res_type.IsDynamicType() &&
- (res_type.IsVoidType() ||
- !(res_type.IsSubtypeOf(other_res_type, malformed_error) ||
- other_res_type.IsSubtypeOf(res_type, malformed_error)))) {
+ if (res_type.IsVoidType()) {
return false;
}
+ if (test_kind == kIsSubtypeOf) {
+ if (!res_type.IsSubtypeOf(other_res_type, malformed_error) &&
+ !other_res_type.IsSubtypeOf(res_type, malformed_error)) {
+ return false;
+ }
+ } else {
+ ASSERT(test_kind == kIsMoreSpecificThan);
+ if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) {
+ return false;
+ }
+ }
}
// Check the types of fixed parameters.
for (intptr_t i = 0; i < num_fixed_params; i++) {
- if (!TestParameterType(i, type_arguments, other, other_type_arguments,
+ if (!TestParameterType(test_kind,
+ i, type_arguments, other, other_type_arguments,
malformed_error)) {
return false;
}
@@ -3841,7 +3867,8 @@
// Check that for each optional named parameter of type T of the other
// function type, there is a corresponding optional named parameter of this
// function at the same position with an identical name and with a type S
- // that is a subtype or supertype of T.
+ // that is a either a subtype or supertype of T (if test_kind == kIsSubtypeOf)
+ // or that is more specific than T (if test_kind == kIsMoreSpecificThan).
// Note that SetParameterNameAt() guarantees that names are symbols, so we
// can compare their raw pointers.
const intptr_t other_num_params =
@@ -3850,7 +3877,8 @@
for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) {
other_param_name = other.ParameterNameAt(i);
if ((ParameterNameAt(i) != other_param_name.raw()) ||
- !TestParameterType(i, type_arguments, other, other_type_arguments,
+ !TestParameterType(test_kind,
+ i, type_arguments, other, other_type_arguments,
malformed_error)) {
return false;
}
« 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