+2003-12-19 Martin Baulig <martin@ximian.com>
+
+ * class.c (mono_class_initialize_generic): Made this static, take
+ a `MonoGenericInst *' instead of a `MonoClass *'.
+ (mono_class_from_generic): Call mono_class_initialize_generic()
+ unless we're already initialized or being called from
+ do_mono_metadata_parse_generic_inst().
+
+ * class.h (MonoGenericInst): Added `initialized' and
+ `init_pending' flags.
+
+ * metadata.c (do_mono_metadata_parse_generic_inst): Don't call
+ `mono_class_init (gklass)' or mono_class_initialize_generic()
+ here; set `generic_inst->init_pending' while parsing the
+ `type_argv'.
+
2003-12-19 Bernie Solomon <bernard@ugsolutions.com>
* locales.c: include string.h for memxxx prototypes
return g_string_free (res, FALSE);
}
-void
-mono_class_initialize_generic (MonoClass *class, gboolean inflate_methods)
+static void
+mono_class_initialize_generic (MonoGenericInst *ginst, gboolean inflate_methods)
{
- MonoGenericInst *ginst = class->generic_inst->data.generic_inst;
- MonoClass *gklass = mono_class_from_mono_type (ginst->generic_type);
+ MonoClass *klass, *gklass;
- if (class->name)
+ if (ginst->initialized || ginst->init_pending)
return;
- class->name = get_instantiation_name (gklass->name, ginst);
+ gklass = mono_class_from_mono_type (ginst->generic_type);
+ mono_class_init (gklass);
+
+ klass = ginst->klass;
+ klass->name = get_instantiation_name (gklass->name, ginst);
+
+ mono_class_setup_parent (klass, gklass->parent);
+ mono_class_setup_mono_type (klass);
if (inflate_methods) {
int i;
- mono_class_setup_parent (class, gklass->parent);
- mono_class_setup_mono_type (class);
-
- class->field = gklass->field;
- class->method = gklass->method;
- class->methods = g_new0 (MonoMethod *, class->method.count);
- for (i = 0; i < class->method.count; i++)
- class->methods [i] = mono_class_inflate_generic_method (gklass->methods [i], ginst);
+ klass->field = gklass->field;
+ klass->method = gklass->method;
+ klass->methods = g_new0 (MonoMethod *, klass->method.count);
+ for (i = 0; i < klass->method.count; i++)
+ klass->methods [i] = mono_class_inflate_generic_method (gklass->methods [i], ginst);
}
- g_hash_table_insert (class->image->generics_cache, ginst->generic_type, class);
+ g_hash_table_insert (klass->image->generics_cache, ginst->generic_type, klass);
+ ginst->initialized = TRUE;
}
MonoClass*
MonoClass *class, *gklass;
MonoImage *image;
- if (ginst->klass)
+ if (ginst->klass) {
+ mono_class_initialize_generic (ginst, TRUE);
return ginst->klass;
+ }
mono_loader_lock ();
MonoMethod *generic_method;
int type_argc;
MonoType **type_argv;
- guint32 is_open;
+ guint is_open : 1;
+ guint initialized : 1;
+ guint init_pending : 1;
};
struct _MonoGenericParam {
MonoMethod*
mono_class_inflate_generic_method (MonoMethod *method, MonoGenericInst *ginst);
-void
-mono_class_initialize_generic (MonoClass *class, gboolean inflate_methods);
-
MonoClassField*
mono_field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass);
* See mcs/tests/gen-23.cs for an example.
*/
+ generic_inst->init_pending = TRUE;
+
gklass = mono_class_from_mono_type (generic_inst->generic_type);
- mono_class_init (gklass);
klass->name_space = gklass->name_space;
klass->image = m;
for (i = 0; i < generic_inst->type_argc; i++)
generic_inst->type_argv [i] = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
-
- mono_class_initialize_generic (generic_inst->klass, TRUE);
+
+ generic_inst->init_pending = FALSE;
if (rptr)
*rptr = ptr;