2004-10-12 Martin Baulig <martin@ximian.com>
authorMartin Baulig <martin@novell.com>
Tue, 12 Oct 2004 03:11:32 +0000 (03:11 -0000)
committerMartin Baulig <martin@novell.com>
Tue, 12 Oct 2004 03:11:32 +0000 (03:11 -0000)
* metadata.c (mono_metadata_generic_param_equal): We always have
an owner.

* class.c
(mono_class_from_generic_parameter): We need to have an owner.
(my_mono_class_from_generic_parameter): Likewise.

* reflection.c (mono_reflection_setup_generic_class): Renamed to
mono_reflection_create_generic_class() and added a new
mono_reflection_setup_generic_class().
(mono_reflection_initialize_generic_param): If we're a nested
generic type and inherited from the containing class, set our
owner to the outer class.

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

mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/icall.c
mono/metadata/metadata.c
mono/metadata/object-internals.h
mono/metadata/reflection.c

index abe36c6eaeec0633c5e3143bea406f6ca4f1cd4e..bf61c110746884a32ba0c3e205981e840f25822d 100644 (file)
@@ -1,3 +1,19 @@
+2004-10-12  Martin Baulig  <martin@ximian.com>
+
+       * metadata.c (mono_metadata_generic_param_equal): We always have
+       an owner.
+
+       * class.c
+       (mono_class_from_generic_parameter): We need to have an owner.
+       (my_mono_class_from_generic_parameter): Likewise.
+
+       * reflection.c (mono_reflection_setup_generic_class): Renamed to
+       mono_reflection_create_generic_class() and added a new
+       mono_reflection_setup_generic_class().  
+       (mono_reflection_initialize_generic_param): If we're a nested
+       generic type and inherited from the containing class, set our
+       owner to the outer class.
+
 2004-10-11  Zoltan Varga  <vargaz@freemail.hu>
 
        * icall.c (ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal): New icall.
index 8d8d1deded20e85c50dbc23e1905aad927134577..91edad24df35ea9325829bddd232762ba33cdb98 100644 (file)
@@ -1984,7 +1984,7 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb
                        klass->interfaces [i - pos] = param->constraints [i];
        }
 
-       g_assert (param->name);
+       g_assert (param->name && param->owner);
 
        klass->name = param->name;
        klass->name_space = "";
@@ -2010,6 +2010,8 @@ my_mono_class_from_generic_parameter (MonoGenericParam *param, gboolean is_mvar)
        if (param->pklass)
                return param->pklass;
 
+       g_assert (param->owner);
+
        klass = g_new0 (MonoClass, 1);
 
        if (param->name)
index 2b6259a13aa8e151fcd16002c3b6bb86b612a932..f9d71dbe17ebb2bb4001af0fa1b5d2b4e00e0cb0 100644 (file)
@@ -6114,6 +6114,7 @@ static const IcallEntry signaturehelper_icalls [] = {
 };
 
 static const IcallEntry typebuilder_icalls [] = {
+       {"create_generic_class", mono_reflection_create_generic_class},
        {"create_internal_class", mono_reflection_create_internal_class},
        {"create_runtime_class", mono_reflection_create_runtime_class},
        {"get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter},
index 197f9806d9f4ff7ad941ca2a263ebe8d456b2d13..cd727266effe6aa044b35c00eb37c9a1873ecf09 100644 (file)
@@ -2669,23 +2669,19 @@ mono_metadata_generic_param_equal (MonoGenericParam *p1, MonoGenericParam *p2, g
        if (p1->num != p2->num)
                return FALSE;
 
+       g_assert (p1->owner && p2->owner);
+       if (p1->owner == p2->owner)
+               return TRUE;
+
        /*
-        * FIXME: Normally each MonoGenericParam should have a non-NULL owner.
+        * This should only happen for dynamic type parameters; we copy them from the
+        * MonoReflectionGenericParam into the newly created MonoGenericContainer, so their
+        * addresses may be different.
         */
-       if (p1->owner && (p1->owner == p2->owner))
+       if (p1->owner->klass && (p1->owner->klass == p2->owner->klass))
+               return TRUE;
+       if (p1->owner->method && (p1->owner->method == p2->owner->method))
                return TRUE;
-
-       if (p1->owner && p2->owner) {
-               /*
-                * This should only happen for dynamic type parameters; we copy them from the
-                * MonoReflectionGenericParam into the newly created MonoGenericContainer, so their
-                * addresses may be different.
-                */
-               if (p1->owner->klass && (p1->owner->klass == p2->owner->klass))
-                       return TRUE;
-               if (p1->owner->method && (p1->owner->method == p2->owner->method))
-                       return TRUE;
-       }
 
        /*
         * If `signature_only' is true, we're comparing two (method) signatures.
index 410fb1b2e84fe48f41d02ce8b95c6a294618e91a..b2bbedc4737219019637c027371b09ba66b49ddc 100644 (file)
@@ -927,6 +927,8 @@ void        mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb
 
 void        mono_reflection_setup_generic_class   (MonoReflectionTypeBuilder *tb);
 
+void        mono_reflection_create_generic_class  (MonoReflectionTypeBuilder *tb);
+
 MonoReflectionType* mono_reflection_create_runtime_class  (MonoReflectionTypeBuilder *tb);
 
 void mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *m);
index ba00927d06ac98225ee585703083695f0c0da0c6..979e7b0c85117c91ed69d951941eb040658f1c01 100644 (file)
@@ -7284,7 +7284,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
  * mono_reflection_setup_generic_class:
  * @tb: a TypeBuilder object
  *
- * Setup the generic class after all generic parameters have been added.
+ * Setup the generic class before adding the first generic parameter.
  */
 void
 mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
@@ -7295,6 +7295,28 @@ mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
+       klass = my_mono_class_from_mono_type (tb->type.type);
+       if (tb->generic_container)
+               return;
+
+       tb->generic_container = g_new0 (MonoGenericContainer, 1);
+       tb->generic_container->klass = klass;
+}
+
+/*
+ * mono_reflection_create_generic_class:
+ * @tb: a TypeBuilder object
+ *
+ * Creates the generic class after all generic parameters have been added.
+ */
+void
+mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
+{
+       MonoClass *klass;
+       int count, i;
+
+       MONO_ARCH_SAVE_REGS;
+
        klass = my_mono_class_from_mono_type (tb->type.type);
 
        count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
@@ -7302,17 +7324,17 @@ mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
        if (klass->generic_container || (count == 0))
                return;
 
-       klass->generic_container = container = g_new0 (MonoGenericContainer, 1);
+       g_assert (tb->generic_container && (tb->generic_container->klass == klass));
+
+       klass->generic_container = tb->generic_container;
 
-       container->klass = klass;
-       container->type_argc = count;
-       container->type_params = g_new0 (MonoGenericParam, count);
+       klass->generic_container->type_argc = count;
+       klass->generic_container->type_params = g_new0 (MonoGenericParam, count);
 
        for (i = 0; i < count; i++) {
                MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
-               container->type_params [i] = *gparam->type.type->data.generic_param;
-               gparam->type.type->data.generic_param->owner = container;
-               container->type_params [i].owner = container;
+               klass->generic_container->type_params [i] = *gparam->type.type->data.generic_param;
+               g_assert (klass->generic_container->type_params [i].owner);
        }
 }
 
@@ -8400,12 +8422,22 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
                        gparam->mbuilder->generic_container = g_new0 (MonoGenericContainer, 1);
                param->owner = gparam->mbuilder->generic_container;
        } else if (gparam->tbuilder) {
-               if (!gparam->tbuilder->generic_container) {
-                       MonoClass *klass = my_mono_class_from_mono_type (gparam->tbuilder->type.type);
-                       gparam->tbuilder->generic_container = g_new0 (MonoGenericContainer, 1);
-                       gparam->tbuilder->generic_container->klass = klass;
+               MonoReflectionTypeBuilder *nesting = gparam->tbuilder->nesting_type;
+               MonoGenericContainer *container = gparam->tbuilder->generic_container;
+
+               while (nesting) {
+                       int count;
+
+                       count = nesting->generic_params ? mono_array_length (nesting->generic_params) : 0;
+                       if (gparam->index >= count)
+                               break;
+
+                       container = nesting->generic_container;
+                       nesting = nesting->nesting_type;
                }
-               param->owner = gparam->tbuilder->generic_container;
+
+               g_assert (container);
+               param->owner = container;
        }
 
        param->method = NULL;