2003-12-19 Martin Baulig <martin@ximian.com>
authorMartin Baulig <martin@novell.com>
Fri, 19 Dec 2003 20:43:51 +0000 (20:43 -0000)
committerMartin Baulig <martin@novell.com>
Fri, 19 Dec 2003 20:43:51 +0000 (20:43 -0000)
* 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'.

svn path=/trunk/mono/; revision=21364

mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/class.h
mono/metadata/metadata.c

index 5bea0d8609559e4854bcb1e590ee9aaa8651c4b7..867e544345114cbfc6972cc70a27946cf098eca4 100644 (file)
@@ -1,3 +1,19 @@
+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
index 776f85981efb37143c9cc53dd11c2ac39a41ff76..6e56f1a444d57d5659e128844b4d86aad61214e4 100644 (file)
@@ -1629,31 +1629,35 @@ get_instantiation_name (const char *name, MonoGenericInst *ginst)
        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*
@@ -1663,8 +1667,10 @@ mono_class_from_generic (MonoType *gtype, gboolean inflate_methods)
        MonoClass *class, *gklass;
        MonoImage *image;
 
-       if (ginst->klass)
+       if (ginst->klass) {
+               mono_class_initialize_generic (ginst, TRUE);
                return ginst->klass;
+       }
 
        mono_loader_lock ();
 
index cc7aa85aaeb44b78db8b992118daa098ff41214a..71b341a554a80e1fbdd3ce4f26dce84239a69480 100644 (file)
@@ -221,7 +221,9 @@ struct _MonoGenericInst {
        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 {
@@ -306,9 +308,6 @@ mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig
 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);
 
index 65e56c1b3c0ec41a096f8cd8f9f3789852b697b3..eaa1cf94ff311c7240086584d38c4b18fc73b3c7 100644 (file)
@@ -1448,8 +1448,9 @@ do_mono_metadata_parse_generic_inst (MonoType *type, MonoImage *m, const char *p
         * 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;
@@ -1461,8 +1462,8 @@ do_mono_metadata_parse_generic_inst (MonoType *type, MonoImage *m, const char *p
 
        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;