Author: martin
Date: 2005-12-14 17:09:19 -0500 (Wed, 14 Dec 2005)
New Revision: 54414

Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/class.c
   trunk/mono/mono/metadata/icall.c
   trunk/mono/mono/metadata/reflection.c
Log:
2005-12-14  Martin Baulig  <[EMAIL PROTECTED]>

        * class.c
        (mono_type_get_name_recurse): Don't return null for type
        parameters and open generic classes.
        (mono_class_setup_methods): Don't exclude generic instances.
        (mono_get_unique_iid): Use different IDs for different
        instantiations of the same generic type.
        (mono_class_setup_vtable): Only use setup_generic_vtable() for
        open generic instances; create a normal vtable for closed generic
        instances.
        (mono_class_setup_vtable_general): We're now also called for
        closed generic instances.

        * reflection.c
        (mono_reflection_bind_generic_parameters): Correctly use
        mono_metadata_lookup_generic_inst() everywhere.



Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2005-12-14 21:59:28 UTC (rev 54413)
+++ trunk/mono/mono/metadata/ChangeLog  2005-12-14 22:09:19 UTC (rev 54414)
@@ -1,3 +1,21 @@
+2005-12-14  Martin Baulig  <[EMAIL PROTECTED]>
+
+       * class.c
+       (mono_type_get_name_recurse): Don't return null for type
+       parameters and open generic classes.
+       (mono_class_setup_methods): Don't exclude generic instances.
+       (mono_get_unique_iid): Use different IDs for different
+       instantiations of the same generic type.
+       (mono_class_setup_vtable): Only use setup_generic_vtable() for
+       open generic instances; create a normal vtable for closed generic
+       instances.
+       (mono_class_setup_vtable_general): We're now also called for
+       closed generic instances.
+
+       * reflection.c
+       (mono_reflection_bind_generic_parameters): Correctly use
+       mono_metadata_lookup_generic_inst() everywhere.
+
 2005-12-14  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * loader.c (mono_loader_set_error_type_load): Print the type load

Modified: trunk/mono/mono/metadata/class.c
===================================================================
--- trunk/mono/mono/metadata/class.c    2005-12-14 21:59:28 UTC (rev 54413)
+++ trunk/mono/mono/metadata/class.c    2005-12-14 22:09:19 UTC (rev 54414)
@@ -328,11 +328,6 @@
 {
        GString* result;
 
-       if (format == MONO_TYPE_NAME_FORMAT_FULL_NAME &&
-           ((type->type == MONO_TYPE_VAR) || (type->type == MONO_TYPE_MVAR) ||
-            ((type->type == MONO_TYPE_GENERICINST) && 
type->data.generic_class->inst->is_open)))
-               return NULL;
-
        result = g_string_new ("");
 
        mono_type_get_name_recurse (type, result, FALSE, format);
@@ -1163,7 +1158,7 @@
        int i;
        MonoMethod **methods;
 
-       if (class->methods || class->generic_class)
+       if (class->methods)
                return;
 
        mono_loader_lock ();
@@ -1175,7 +1170,7 @@
 
        //printf ("INIT: %s.%s\n", class->name_space, class->name);
 
-       if (!class->generic_class && !class->methods) {
+       if (!class->methods) {
                methods = mono_mempool_alloc (class->image->mempool, sizeof 
(MonoMethod*) * class->method.count);
                for (i = 0; i < class->method.count; ++i) {
                        methods [i] = mono_get_method (class->image, 
MONO_TOKEN_METHOD_DEF | (i + class->method.first + 1), class);
@@ -1327,6 +1322,7 @@
 
        char *str;
        gpointer value;
+       int generic_id;
        
        g_assert (MONO_CLASS_IS_INTERFACE (class));
 
@@ -1335,8 +1331,15 @@
        if (!iid_hash)
                iid_hash = g_hash_table_new (g_str_hash, g_str_equal);
 
-       str = g_strdup_printf ("%s|%s.%s\n", class->image->name, 
class->name_space, class->name);
+       if (class->generic_class && !class->generic_class->inst->is_open) {
+               generic_id = class->generic_class->inst->id;
+               g_assert (generic_id != 0);
+       } else
+               generic_id = 0;
 
+       str = g_strdup_printf ("%s|%s.%s|%d", class->image->name, 
class->name_space, class->name,
+                              generic_id);
+
        if (g_hash_table_lookup_extended (iid_hash, str, NULL, &value)) {
                mono_loader_unlock ();
                g_free (str);
@@ -1526,11 +1529,42 @@
        return cur_slot;
 }
 
+static void
+setup_generic_vtable (MonoClass *class)
+{
+       MonoClass *gklass;
+       int i;
+
+       gklass = class->generic_class->container_class;
+
+       mono_class_init (gklass);
+       class->vtable_size = gklass->vtable_size;
+
+       class->vtable = g_new0 (MonoMethod*, class->vtable_size);
+       memcpy (class->vtable, gklass->vtable,  sizeof (MonoMethod*) * 
class->vtable_size);
+
+       for (i = 0; i < class->vtable_size; i++) {
+               MonoMethod *m = class->vtable [i];
+
+               if (!m)
+                       continue;
+
+               m = mono_class_inflate_generic_method (m, 
class->generic_class->context);
+               class->vtable [i] = m;
+       }
+
+       class->max_interface_id = gklass->max_interface_id;
+       class->interface_offsets = g_new0 (gint, gklass->max_interface_id + 1);
+       memcpy (class->interface_offsets, gklass->interface_offsets,
+               sizeof (gint) * (gklass->max_interface_id + 1));
+}
+
 void
 mono_class_setup_vtable (MonoClass *class)
 {
        MonoMethod **overrides;
        MonoGenericContext *context;
+       guint32 type_token;
        int onum = 0;
 
        if (class->vtable)
@@ -1548,48 +1582,27 @@
                return;
        }
 
-       if (class->generic_class)
+       if (class->generic_class) {
+               if (class->generic_class->inst->is_open) {
+                       setup_generic_vtable (class);
+                       mono_loader_unlock ();
+                       return;
+               }
+
                context = class->generic_class->context;
-       else
+               type_token = class->generic_class->container_class->type_token;
+       } else {
                context = (MonoGenericContext *) class->generic_container;      
        
+               type_token = class->type_token;
+       }
 
-       mono_class_get_overrides_full (class->image, class->type_token, 
&overrides, &onum, context);
+       mono_class_get_overrides_full (class->image, type_token, &overrides, 
&onum, context);
        mono_class_setup_vtable_general (class, overrides, onum);
        g_free (overrides);
 
        mono_loader_unlock ();
 }
 
-static void
-setup_generic_vtable (MonoClass *class, MonoMethod **overrides, int onum)
-{
-       MonoClass *gklass;
-       int i;
-
-       gklass = class->generic_class->container_class;
-
-       mono_class_init (gklass);
-       class->vtable_size = gklass->vtable_size;
-
-       class->vtable = g_new0 (MonoMethod*, class->vtable_size);
-       memcpy (class->vtable, gklass->vtable,  sizeof (MonoMethod*) * 
class->vtable_size);
-
-       for (i = 0; i < class->vtable_size; i++) {
-               MonoMethod *m = class->vtable [i];
-
-               if (!m)
-                       continue;
-
-               m = mono_class_inflate_generic_method (m, 
class->generic_class->context);
-               class->vtable [i] = m;
-       }
-
-       class->max_interface_id = gklass->max_interface_id;
-       class->interface_offsets = g_new0 (gint, gklass->max_interface_id + 1);
-       memcpy (class->interface_offsets, gklass->interface_offsets,
-               sizeof (gint) * (gklass->max_interface_id + 1));
-}
-
 /*
  * LOCKING: this is supposed to be called with the loader lock held.
  */
@@ -1599,15 +1612,15 @@
        MonoClass *k, *ic;
        MonoMethod **vtable;
        int i, max_vtsize = 0, max_iid, cur_slot = 0;
-       GPtrArray *ifaces;
+       GPtrArray *ifaces, *pifaces = NULL;
        GHashTable *override_map = NULL;
        gboolean security_enabled = mono_is_security_manager_active ();
 
        if (class->vtable)
                return;
 
-       if (class->generic_class) {
-               setup_generic_vtable (class, overrides, onum);
+       if (class->generic_class && class->generic_class->inst->is_open) {
+               setup_generic_vtable (class);
                return;
        }
 
@@ -1661,12 +1674,22 @@
                int nifaces = 0;
 
                ifaces = mono_class_get_implemented_interfaces (k);
-               if (ifaces)
+               if (ifaces) {
                        nifaces = ifaces->len;
+                       if (k->generic_class) {
+                               pifaces = mono_class_get_implemented_interfaces 
(
+                                       k->generic_class->container_class);
+                               g_assert (pifaces && (pifaces->len == nifaces));
+                       }
+               }
                for (i = 0; i < nifaces; i++) {
+                       MonoClass *pic = NULL;
                        int j, l, io;
 
                        ic = g_ptr_array_index (ifaces, i);
+                       if (pifaces)
+                               pic = g_ptr_array_index (pifaces, i);
+                       g_assert (ic->interface_id <= k->max_interface_id);
                        io = k->interface_offsets [ic->interface_id];
 
                        g_assert (io >= 0);
@@ -1750,8 +1773,8 @@
                                if (vtable [io + l])
                                        continue;
 
-                               if (ic->generic_class) {
-                                       the_cname = mono_type_get_name_full 
(&ic->byval_arg, MONO_TYPE_NAME_FORMAT_IL);
+                               if (pic) {
+                                       the_cname = mono_type_get_name_full 
(&pic->byval_arg, MONO_TYPE_NAME_FORMAT_IL);
                                        cname = the_cname;
                                } else {
                                        the_cname = NULL;
@@ -1823,7 +1846,7 @@
                                                g_free (msig);
                                                for (j = 0; j < 
class->method.count; ++j) {
                                                        MonoMethod *cm = 
class->methods [j];
-                                                       msig = 
mono_signature_get_desc (mono_method_signature (cm), FALSE);
+                                                       msig = 
mono_signature_get_desc (mono_method_signature (cm), TRUE);
                                                        
                                                        printf ("METHOD 
%s(%s)\n", cm->name, msig);
                                                        g_free (msig);
@@ -1936,8 +1959,9 @@
                MonoClass *gklass = class->generic_class->container_class;
 
                mono_class_init (gklass);
-               class->vtable_size = gklass->vtable_size;
-       } else       
+
+               class->vtable_size = MAX (gklass->vtable_size, cur_slot);
+       } else
                class->vtable_size = cur_slot;
 
        class->vtable = g_malloc0 (sizeof (gpointer) * class->vtable_size);

Modified: trunk/mono/mono/metadata/icall.c
===================================================================
--- trunk/mono/mono/metadata/icall.c    2005-12-14 21:59:28 UTC (rev 54413)
+++ trunk/mono/mono/metadata/icall.c    2005-12-14 22:09:19 UTC (rev 54414)
@@ -957,6 +957,26 @@
        mono_image_build_metadata (mb);
 }
 
+static gboolean
+get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer 
data)
+{
+       MonoMethod **dest = data;
+
+       /* skip unmanaged frames */
+       if (!managed)
+               return FALSE;
+
+       if (m == *dest) {
+               *dest = NULL;
+               return FALSE;
+       }
+       if (!(*dest)) {
+               *dest = m;
+               return TRUE;
+       }
+       return FALSE;
+}
+
 static MonoReflectionType *
 type_from_name (const char *str, MonoBoolean ignoreCase)
 {
@@ -979,10 +999,27 @@
        if (info.assembly.name) {
                assembly = mono_assembly_load (&info.assembly, NULL, NULL);
        } else {
-               MonoReflectionAssembly *refass;
+               MonoMethod *m = mono_method_get_last_managed ();
+               MonoMethod *dest = m;
 
-               refass = 
ves_icall_System_Reflection_Assembly_GetCallingAssembly  ();
-               assembly = refass->assembly;
+               mono_stack_walk_no_il (get_caller, &dest);
+               if (!dest)
+                       dest = m;
+
+               /*
+                * FIXME: mono_method_get_last_managed() sometimes returns 
NULL, thus
+                *        causing 
ves_icall_System_Reflection_Assembly_GetCallingAssembly()
+                *        to crash.  This only seems to happen in some strange 
remoting
+                *        scenarios and I was unable to figure out what's 
happening there.
+                *        Dec 10, 2005 - Martin.
+                */
+
+               if (dest)
+                       assembly = dest->klass->image->assembly;
+               else {
+                       g_warning (G_STRLOC);
+                       raise (19);
+               }
        }
 
        if (assembly)
@@ -4081,26 +4118,6 @@
 }
 
 
-static gboolean
-get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer 
data)
-{
-       MonoMethod **dest = data;
-
-       /* skip unmanaged frames */
-       if (!managed)
-               return FALSE;
-
-       if (m == *dest) {
-               *dest = NULL;
-               return FALSE;
-       }
-       if (!(*dest)) {
-               *dest = m;
-               return TRUE;
-       }
-       return FALSE;
-}
-
 static MonoReflectionAssembly*
 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
 {
@@ -4114,7 +4131,6 @@
        return mono_assembly_get_object (domain, domain->entry_assembly);
 }
 
-
 static MonoReflectionAssembly*
 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
 {

Modified: trunk/mono/mono/metadata/reflection.c
===================================================================
--- trunk/mono/mono/metadata/reflection.c       2005-12-14 21:59:28 UTC (rev 
54413)
+++ trunk/mono/mono/metadata/reflection.c       2005-12-14 22:09:19 UTC (rev 
54414)
@@ -140,8 +140,8 @@
 static guint32 type_get_signature_size (MonoType *type);
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, 
guint32 *types);
 static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType 
*type, const char *blob);
+static inline MonoType *dup_type (const MonoType *original);
 
-
 static void
 alloc_table (MonoDynamicTable *table, guint nrows)
 {
@@ -8530,16 +8530,21 @@
        gclass->inst = g_new0 (MonoGenericInst, 1);
 
        gclass->inst->type_argc = type_argc;
-       gclass->inst->type_argv = types;
+       gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
        gclass->inst->is_reference = 1;
 
        for (i = 0; i < gclass->inst->type_argc; ++i) {
+               MonoType *t = dup_type (types [i]);
+
                if (!gclass->inst->is_open)
-                       gclass->inst->is_open = 
mono_class_is_open_constructed_type (types [i]);
+                       gclass->inst->is_open = 
mono_class_is_open_constructed_type (t);
                if (gclass->inst->is_reference)
-                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE 
(types [i]);
+                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
+               gclass->inst->type_argv [i] = t;
        }
 
+       gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
        gclass->container_class = klass;
 
        if (klass->generic_class) {
@@ -8581,6 +8586,8 @@
                        gclass->inst->type_argv [i] = t;
                }
 
+               gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
                gclass->container_class = kgclass->container_class;
        }
 
@@ -8701,16 +8708,22 @@
 
        gclass->inst = g_new0 (MonoGenericInst, 1);
        gclass->inst->type_argc = type_argc;
-       gclass->inst->type_argv = types;
+       gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
        gclass->inst->is_reference = 1;
 
        for (i = 0; i < gclass->inst->type_argc; ++i) {
+               MonoType *t = dup_type (types [i]);
+
                if (!gclass->inst->is_open)
-                       gclass->inst->is_open = 
mono_class_is_open_constructed_type (types [i]);
+                       gclass->inst->is_open = 
mono_class_is_open_constructed_type (t);
                if (gclass->inst->is_reference)
-                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE 
(types [i]);
+                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
+
+               gclass->inst->type_argv [i] = t;
        }
 
+       gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
        gclass->container_class = klass;
 
        if (klass->generic_class) {
@@ -8743,6 +8756,8 @@
                        gclass->inst->type_argv [i] = t;
                }
 
+               gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
                gclass->container_class = kgclass->container_class;
        }
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to