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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 2806893002: Make finalization of recursive function types more robust, especially since (Closed)
Patch Set: updated tests status and sync 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/class_finalizer.cc
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index e100cc529ac20a1f76be3db3a729e021f03438aa..ab89f7fcdbd7ae52aa732ad7d0aa92005c395326 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -815,19 +815,8 @@ intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments(
}
}
- // Self referencing types may get finalized indirectly.
- if (!type.IsFinalized()) {
- ASSERT(full_arguments.IsNull() ||
- !full_arguments.IsRaw(0, num_type_arguments));
- if (FLAG_trace_type_finalization) {
- THR_Print("Marking type '%s' as finalized for class '%s'\n",
- String::Handle(zone, type.Name()).ToCString(),
- String::Handle(zone, cls.Name()).ToCString());
- }
- // Mark the type as finalized.
- type.SetIsFinalized();
- // Do not yet remove the type from the pending_types array.
- }
+ ASSERT(full_arguments.IsNull() ||
+ !full_arguments.IsRaw(0, num_type_arguments));
return full_arguments.IsNull() ? 0 : full_arguments.Length();
}
@@ -1225,6 +1214,57 @@ RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
const intptr_t num_expanded_type_arguments =
ExpandAndFinalizeTypeArguments(cls, type, pending_types);
+ // Self referencing types may get finalized indirectly.
+ if (!type.IsFinalized()) {
+ // If the type is a function type, we also need to finalize the types in its
+ // signature, i.e. finalize the result type and parameter types of the
+ // signature function of this function type.
+ // We do this after marking this type as finalized in order to allow a
+ // typedef function type to refer to itself via its parameter types and
+ // result type.
+ if (type.IsFunctionType()) {
+ const Type& fun_type = Type::Cast(type);
+ const Class& scope_class = Class::Handle(zone, fun_type.type_class());
+ if (scope_class.IsTypedefClass()) {
+ Function& signature =
+ Function::Handle(zone, scope_class.signature_function());
+ if (!scope_class.is_type_finalized()) {
+ FinalizeSignature(scope_class, signature);
+ }
+ // If the function type is a generic typedef, instantiate its signature
+ // from its type arguments.
+ // Example: typedef T F<T>(T x) has uninstantiated signature (T x) => T.
+ // The instantiated signature of F(int) becomes (int x) => int.
+ // Note that after this step, the signature of the function type is not
+ // identical to the canonical signature of the typedef class anymore.
+ if (scope_class.IsGeneric() && !signature.HasInstantiatedSignature()) {
+ const TypeArguments& type_args =
+ TypeArguments::Handle(zone, fun_type.arguments());
+ if (FLAG_trace_type_finalization) {
+ THR_Print("Instantiating signature '%s' of typedef '%s'\n",
+ String::Handle(zone, signature.Signature()).ToCString(),
+ String::Handle(zone, fun_type.Name()).ToCString());
+ }
+ signature = signature.InstantiateSignatureFrom(type_args, Heap::kOld);
+ // Note that if type_args contains type parameters, signature is still
+ // uninstantiated here (typedef type parameters were substituted in
+ // the signature with typedef type arguments).
+ }
+ fun_type.set_signature(signature);
+ } else {
+ FinalizeSignature(cls, Function::Handle(zone, fun_type.signature()));
+ }
+ }
+
+ if (FLAG_trace_type_finalization) {
+ THR_Print("Marking type '%s' as finalized for class '%s'\n",
+ String::Handle(zone, type.Name()).ToCString(),
+ String::Handle(zone, cls.Name()).ToCString());
+ }
+ // Mark the type as finalized.
+ type.SetIsFinalized();
+ }
+
// If we are done finalizing a graph of mutually recursive types, check their
// bounds.
if (is_root_type) {
@@ -1236,52 +1276,6 @@ RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
}
}
- // If the type is a function type, we also need to finalize the types in its
- // signature, i.e. finalize the result type and parameter types of the
- // signature function of this function type.
- // We do this after marking this type as finalized in order to allow a
- // typedef function type to refer to itself via its parameter types and
- // result type.
- if (type.IsFunctionType()) {
- ASSERT(!type.IsBeingFinalized());
- const Type& fun_type = Type::Cast(type);
- const Class& scope_class = Class::Handle(zone, fun_type.type_class());
- if (scope_class.IsTypedefClass()) {
- Function& signature =
- Function::Handle(zone, scope_class.signature_function());
- if (!scope_class.is_type_finalized()) {
- FinalizeSignature(scope_class, signature);
- }
- // If the function type is a generic typedef, instantiate its signature
- // from its type arguments.
- // Example: typedef T F<T>(T x) has uninstantiated signature (T x) => T.
- // The instantiated signature of F(int) becomes (int x) => int.
- // Note that after this step, the signature of the function type is not
- // identical to the canonical signature of the typedef class anymore.
- if (scope_class.IsGeneric() && !signature.HasInstantiatedSignature()) {
- const TypeArguments& type_args =
- TypeArguments::Handle(zone, fun_type.arguments());
- if (FLAG_trace_type_finalization) {
- THR_Print("Instantiating signature '%s' of typedef '%s'\n",
- String::Handle(zone, signature.Signature()).ToCString(),
- String::Handle(zone, fun_type.Name()).ToCString());
- }
- signature = signature.InstantiateSignatureFrom(type_args, Heap::kOld);
- // Note that if type_args contains type parameters, signature is still
- // uninstantiated here (typedef type parameters were substituted in the
- // signature with typedef type arguments).
- }
- fun_type.set_signature(signature);
- // The type was already marked as finalized and uninstantiated in
- // ExpandAndFinalizeTypeArguments above when its signature was not
- // instantiated yet. Check again by calling ResetIsFinalized().
- fun_type.ResetIsFinalized();
- } else {
- const Function& signature = Function::Handle(zone, fun_type.signature());
- FinalizeSignature(cls, signature);
- }
- }
-
if (FLAG_trace_type_finalization) {
THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n",
String::Handle(zone, type.Name()).ToCString(),
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698