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

Unified Diff: runtime/vm/object.cc

Issue 2951803005: Set and keep parent function of signature functions. (Closed)
Patch Set: address review comments Created 3 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') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 4d9b87c7dcac5ecf194c992817356f290f8186f3..76f9a2a167a512c8dd5ffceb1e1f7e9fb18ec3b2 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -6525,10 +6525,11 @@ RawFunction* Function::InstantiateSignatureFrom(
Heap::Space space) const {
Zone* zone = Thread::Current()->zone();
const Object& owner = Object::Handle(zone, RawOwner());
+ const Function& parent = Function::Handle(zone, parent_function());
ASSERT(!HasInstantiatedSignature());
Function& sig = Function::Handle(
- zone,
- Function::NewSignatureFunction(owner, TokenPosition::kNoSource, space));
+ zone, Function::NewSignatureFunction(owner, parent,
+ TokenPosition::kNoSource, space));
sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
AbstractType& type = AbstractType::Handle(zone, result_type());
if (!type.IsInstantiated()) {
@@ -6919,6 +6920,7 @@ RawFunction* Function::NewClosureFunction(const String& name,
RawFunction* Function::NewSignatureFunction(const Object& owner,
+ const Function& parent,
TokenPosition token_pos,
Heap::Space space) {
const Function& result = Function::Handle(Function::New(
@@ -6930,6 +6932,7 @@ RawFunction* Function::NewSignatureFunction(const Object& owner,
/* is_native = */ false,
owner, // Same as function type scope class.
token_pos, space));
+ result.set_parent_function(parent);
result.set_is_reflectable(false);
result.set_is_visible(false);
result.set_is_debuggable(false);
@@ -16815,9 +16818,22 @@ bool AbstractType::TypeTest(TypeTestKind test_kind,
// TODO(regis): Should we update TypeParameter::IsEquivalent() instead?
if (type_param.IsFunctionTypeParameter() &&
other_type_param.IsFunctionTypeParameter() &&
- type_param.IsFinalized() && other_type_param.IsFinalized() &&
- (type_param.index() == other_type_param.index())) {
- return true;
+ type_param.IsFinalized() && other_type_param.IsFinalized()) {
+ // To be compatible, the function type parameters should be declared at
+ // the same position in the generic function. Their index therefore
+ // needs adjustement before comparison.
+ // Example: 'foo<F>(bar<B>(B b)) { }' and 'baz<Z>(Z z) { }', baz can be
+ // assigned to bar, although B has index 1 and Z index 0.
+ const Function& sig_fun =
+ Function::Handle(zone, type_param.parameterized_function());
+ const Function& other_sig_fun =
+ Function::Handle(zone, other_type_param.parameterized_function());
+ const int offset = sig_fun.NumParentTypeParameters();
+ const int other_offset = other_sig_fun.NumParentTypeParameters();
+ if (type_param.index() - offset ==
+ other_type_param.index() - other_offset) {
+ return true;
+ }
}
}
const AbstractType& bound = AbstractType::Handle(zone, type_param.bound());
@@ -17445,8 +17461,10 @@ RawAbstractType* Type::CloneUnfinalized() const {
Function& fun = Function::Handle(zone, signature());
if (!fun.IsNull()) {
const Class& owner = Class::Handle(zone, fun.Owner());
- Function& fun_clone = Function::Handle(
- zone, Function::NewSignatureFunction(owner, TokenPosition::kNoSource));
+ const Function& parent = Function::Handle(zone, fun.parent_function());
+ Function& fun_clone =
+ Function::Handle(zone, Function::NewSignatureFunction(
+ owner, parent, TokenPosition::kNoSource));
const TypeArguments& type_params =
TypeArguments::Handle(zone, fun.type_parameters());
if (!type_params.IsNull()) {
@@ -17513,9 +17531,11 @@ RawAbstractType* Type::CloneUninstantiated(const Class& new_owner,
ASSERT(type_cls.IsTypedefClass() || type_cls.IsClosureClass());
// If the scope class is not a typedef and if it is generic, it must be the
// mixin class, set it to the new owner.
+ const Function& parent = Function::Handle(zone, fun.parent_function());
+ // TODO(regis): Is it safe to reuse the parent function with the old owner?
Function& fun_clone = Function::Handle(
- zone,
- Function::NewSignatureFunction(new_owner, TokenPosition::kNoSource));
+ zone, Function::NewSignatureFunction(new_owner, parent,
+ TokenPosition::kNoSource));
const TypeArguments& type_params =
TypeArguments::Handle(zone, fun.type_parameters());
if (!type_params.IsNull()) {
@@ -17660,11 +17680,18 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
if (IsFunctionType()) {
const Function& fun = Function::Handle(zone, signature());
if (!fun.IsSignatureFunction()) {
- Function& sig_fun = Function::Handle(
- zone,
- Function::NewSignatureFunction(cls, TokenPosition::kNoSource));
+ // In case of a generic function, the function type parameters in the
+ // signature will still refer to the original function. This should not
+ // be a problem, since they are finalized and the indices remain
+ // unchanged.
+ const Function& parent = Function::Handle(zone, fun.parent_function());
+ Function& sig_fun =
+ Function::Handle(zone, Function::NewSignatureFunction(
+ cls, parent, TokenPosition::kNoSource));
sig_fun.set_type_parameters(
TypeArguments::Handle(zone, fun.type_parameters()));
+ ASSERT(fun.HasGenericParent() == sig_fun.HasGenericParent());
+ ASSERT(fun.IsGeneric() == sig_fun.IsGeneric());
type = fun.result_type();
type = type.Canonicalize(trail);
sig_fun.set_result_type(type);
« 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