| 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(),
|
|
|