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

Unified Diff: runtime/vm/object.cc

Issue 988903003: Fix finalization of cyclic mixin types (issue 22666). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 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/regress_22666_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 44305)
+++ runtime/vm/object.cc (working copy)
@@ -4911,7 +4911,8 @@
RawTypeArguments* TypeArguments::CloneUninstantiated(
- const Class& new_owner) const {
+ const Class& new_owner,
+ GrowableObjectArray* trail) const {
ASSERT(!IsNull());
ASSERT(IsFinalized());
ASSERT(!IsInstantiated());
@@ -4922,7 +4923,7 @@
for (intptr_t i = 0; i < num_types; i++) {
type = TypeAt(i);
if (!type.IsInstantiated()) {
- type = type.CloneUninstantiated(new_owner);
+ type = type.CloneUninstantiated(new_owner, trail);
}
clone.SetTypeAt(i, type);
}
@@ -14199,7 +14200,8 @@
RawAbstractType* AbstractType::CloneUninstantiated(
- const Class& new_owner) const {
+ const Class& new_owner,
+ GrowableObjectArray* trail) const {
// AbstractType is an abstract class.
UNREACHABLE();
return NULL;
@@ -14911,16 +14913,29 @@
}
-RawAbstractType* Type::CloneUninstantiated(const Class& new_owner) const {
+RawAbstractType* Type::CloneUninstantiated(const Class& new_owner,
+ GrowableObjectArray* trail) const {
ASSERT(IsFinalized());
ASSERT(!IsMalformed());
if (IsInstantiated()) {
return raw();
}
+ // We may recursively encounter a type already being cloned, because we clone
+ // the upper bounds of its uninstantiated type arguments in the same pass.
+ Type& clone = Type::Handle();
+ clone ^= OnlyBuddyInTrail(trail);
+ if (!clone.IsNull()) {
+ return clone.raw();
+ }
+ const Class& type_cls = Class::Handle(type_class());
+ clone = Type::New(type_cls, TypeArguments::Handle(), token_pos());
TypeArguments& type_args = TypeArguments::Handle(arguments());
- type_args = type_args.CloneUninstantiated(new_owner);
- const Class& type_cls = Class::Handle(type_class());
- const Type& clone = Type::Handle(Type::New(type_cls, type_args, token_pos()));
+ // Upper bounds of uninstantiated type arguments may form a cycle.
+ if (type_args.IsRecursive() || !type_args.IsInstantiated()) {
+ AddOnlyBuddyToTrail(&trail, clone);
+ }
+ type_args = type_args.CloneUninstantiated(new_owner, trail);
+ clone.set_arguments(type_args);
clone.SetIsFinalized();
return clone.raw();
}
@@ -15199,7 +15214,7 @@
ASSERT(!ref_type.IsTypeRef());
AbstractType& instantiated_ref_type = AbstractType::Handle();
instantiated_ref_type = ref_type.InstantiateFrom(
- instantiator_type_arguments, bound_error, trail);
+ instantiator_type_arguments, bound_error, trail);
ASSERT(!instantiated_ref_type.IsTypeRef());
instantiated_type_ref = TypeRef::New(instantiated_ref_type);
AddOnlyBuddyToTrail(&trail, instantiated_type_ref);
@@ -15207,6 +15222,24 @@
}
+RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner,
+ GrowableObjectArray* trail) const {
+ TypeRef& cloned_type_ref = TypeRef::Handle();
+ cloned_type_ref ^= OnlyBuddyInTrail(trail);
+ if (!cloned_type_ref.IsNull()) {
+ return cloned_type_ref.raw();
+ }
+ AbstractType& ref_type = AbstractType::Handle(type());
+ ASSERT(!ref_type.IsTypeRef());
+ AbstractType& cloned_ref_type = AbstractType::Handle();
+ cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail);
+ ASSERT(!cloned_ref_type.IsTypeRef());
+ cloned_type_ref = TypeRef::New(cloned_ref_type);
+ AddOnlyBuddyToTrail(&trail, cloned_type_ref);
+ return cloned_type_ref.raw();
+}
+
+
void TypeRef::set_type(const AbstractType& value) const {
ASSERT(value.HasResolvedTypeClass());
ASSERT(!value.IsTypeRef());
@@ -15463,10 +15496,11 @@
RawAbstractType* TypeParameter::CloneUninstantiated(
- const Class& new_owner) const {
+ const Class& new_owner,
+ GrowableObjectArray* trail) const {
ASSERT(IsFinalized());
AbstractType& upper_bound = AbstractType::Handle(bound());
- upper_bound = upper_bound.CloneUninstantiated(new_owner);
+ upper_bound = upper_bound.CloneUninstantiated(new_owner, trail);
const Class& old_owner = Class::Handle(parameterized_class());
const intptr_t new_index = index() +
new_owner.NumTypeArguments() - old_owner.NumTypeArguments();
@@ -15702,16 +15736,17 @@
RawAbstractType* BoundedType::CloneUninstantiated(
- const Class& new_owner) const {
+ const Class& new_owner,
+ GrowableObjectArray* trail) const {
if (IsInstantiated()) {
return raw();
}
AbstractType& bounded_type = AbstractType::Handle(type());
- bounded_type = bounded_type.CloneUninstantiated(new_owner);
+ bounded_type = bounded_type.CloneUninstantiated(new_owner, trail);
AbstractType& upper_bound = AbstractType::Handle(bound());
- upper_bound = upper_bound.CloneUninstantiated(new_owner);
+ upper_bound = upper_bound.CloneUninstantiated(new_owner, trail);
TypeParameter& type_param = TypeParameter::Handle(type_parameter());
- type_param ^= type_param.CloneUninstantiated(new_owner);
+ type_param ^= type_param.CloneUninstantiated(new_owner, trail);
return BoundedType::New(bounded_type, upper_bound, type_param);
}
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/regress_22666_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698