Hey guys, After talking with Hari I have come to a better solution. First, to fix the case for non dynamic code I have reverted the changes of r80475 and r80445 as suggested by Hari. Reverting theses changes work because the issue was the typebuilder issue pointer previowsly.
The new patch removes mono_class_setup_generic_type_container and the new field in MonoGenericClass, both added on the previous one. I have simplified mono_metadata_is_type_builder_generic_type_definition since MonoGenericInst instances can be compared by pointer for this case. The attached patch full bootstraps, passes all mono regression tests and corlib test suite.
Index: metadata/class.c =================================================================== --- metadata/class.c (revision 86211) +++ metadata/class.c (working copy) @@ -533,6 +533,11 @@ /* We can't use context->class_inst directly, since it can have more elements */ inst = mono_metadata_inflate_generic_inst (container->context.class_inst, context); + /*if the instantiation is the fully open one, we return NULL and the caller will + *use the generic type definition instead*/ + if (inst == container->context.class_inst) + return NULL; + gclass = mono_metadata_lookup_generic_class (klass, inst, klass->image->dynamic); nt = mono_metadata_type_dup (NULL, type); @@ -3271,7 +3276,6 @@ mono_loader_lock (); if (gclass->cached_class) { mono_loader_unlock (); - g_assert (!gclass->cached_class->generic_container); return gclass->cached_class; } @@ -6009,3 +6013,9 @@ return TRUE; } + +gboolean +mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass) +{ + return gklass->context.class_inst == gklass->container_class->generic_container->context.class_inst; +} Index: metadata/metadata.c =================================================================== --- metadata/metadata.c (revision 86211) +++ metadata/metadata.c (working copy) @@ -1430,6 +1430,7 @@ guint hash = mono_metadata_type_hash (&gclass->container_class->byval_arg); hash *= 13; + hash += gclass->is_tb_open; hash += mono_metadata_generic_context_hash (&gclass->context); return hash; @@ -2173,7 +2174,7 @@ int i; /* FIXME: The dynamic case */ - if (gclass->cached_class && !gclass->cached_class->image->dynamic) { + if (gclass->cached_class && !gclass->cached_class->image->dynamic && !mono_generic_class_is_generic_type_definition (gclass)) { MonoClass *class = gclass->cached_class; /* Allocated in mono_class_init () */ @@ -2299,6 +2300,16 @@ return ginst; } +static gboolean +mono_metadata_is_type_builder_generic_type_definition (MonoClass *container_class, MonoGenericInst *inst, gboolean is_dynamic) +{ + MonoGenericContainer *container = container_class->generic_container; + + if (!is_dynamic || container_class->wastypebuilder || container->type_argc != inst->type_argc) + return FALSE; + return inst == container->context.class_inst; +} + /* * mono_metadata_lookup_generic_class: * @@ -2309,12 +2320,14 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst *inst, gboolean is_dynamic) { MonoGenericClass *gclass; + MonoGenericClass helper; + gboolean is_tb_open = mono_metadata_is_type_builder_generic_type_definition (container_class, inst, is_dynamic); - MonoGenericClass helper; helper.container_class = container_class; helper.context.class_inst = inst; helper.context.method_inst = NULL; helper.is_dynamic = is_dynamic; /* We use this in a hash lookup, which does not attempt to downcast the pointer */ + helper.is_tb_open = is_tb_open; helper.cached_class = NULL; mono_loader_lock (); @@ -2337,9 +2350,12 @@ gclass = g_new0 (MonoGenericClass, 1); } + gclass->is_tb_open = is_tb_open; gclass->container_class = container_class; gclass->context.class_inst = inst; gclass->context.method_inst = NULL; + if (inst == container_class->generic_container->context.class_inst && !is_tb_open) + gclass->cached_class = container_class; g_hash_table_insert (generic_class_cache, gclass, gclass); @@ -3746,7 +3762,7 @@ if (!do_mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i], signature_only)) return FALSE; } - return TRUE; + return g1->is_tb_open == g2->is_tb_open; } guint Index: metadata/class-internals.h =================================================================== --- metadata/class-internals.h (revision 86211) +++ metadata/class-internals.h (working copy) @@ -400,6 +400,7 @@ MonoClass *container_class; /* the generic type definition */ MonoGenericContext context; /* a context that contains the type instantiation doesn't contain any method instantiation */ guint is_dynamic : 1; /* We're a MonoDynamicGenericClass */ + guint is_tb_open : 1; /* This is the fully open instantiation for a type_builder*/ MonoClass *cached_class; /* if present, the MonoClass corresponding to the instantiation. */ }; @@ -847,5 +848,8 @@ MonoType * mono_type_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context) MONO_INTERNAL; +gboolean +mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass) MONO_INTERNAL; + #endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */ Index: metadata/reflection.c =================================================================== --- metadata/reflection.c (revision 86211) +++ metadata/reflection.c (working copy) @@ -2428,7 +2428,6 @@ table = &assembly->tables [MONO_TABLE_METHODSPEC]; g_assert (method->is_inflated); - g_assert (!method->klass->generic_container); imethod = (MonoMethodInflated *) method; declaring = imethod->declaring; @@ -8909,6 +8908,7 @@ MONO_ARCH_SAVE_REGS; klass = mono_class_from_mono_type (type->type.type); + g_assert (type->type.type->type == MONO_TYPE_GENERICINST); gclass = type->type.type->data.generic_class; g_assert (gclass->is_dynamic);
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list