2004-12-29 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / metadata.c
index 7d77c99efdaabfa7d5d81623db8cdf2a32cec666..523bec047179b46f0e840cb2847a3fc09e0a45e5 100644 (file)
@@ -27,7 +27,8 @@ static void do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGener
                                         const char *ptr, const char **rptr);
 
 static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only);
-static gboolean _mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2,
+static gboolean mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolean signature_only);
+static gboolean _mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2,
                                                    gboolean signature_only);
 
 /*
@@ -1116,7 +1117,7 @@ mono_metadata_free_array (MonoArrayType *array)
  * private static
  * private static literal
  */
-static MonoType
+static const MonoType
 builtin_types[] = {
        /* data, attrs, type,              nmods, byref, pinned */
        {{NULL}, 0,     MONO_TYPE_VOID,    0,     0,     0},
@@ -1211,7 +1212,7 @@ static guint
 mono_generic_class_hash (gconstpointer data)
 {
        const MonoGenericClass *gclass = (const MonoGenericClass *) data;
-       return mono_metadata_type_hash (gclass->generic_type);
+       return mono_metadata_type_hash (&gclass->container_class->byval_arg);
 }
 
 static gboolean
@@ -1238,7 +1239,7 @@ mono_metadata_init (void)
        generic_class_cache = g_hash_table_new (mono_generic_class_hash, mono_generic_class_equal);
 
        for (i = 0; i < NBUILTIN_TYPES (); ++i)
-               g_hash_table_insert (type_cache, &builtin_types [i], &builtin_types [i]);
+               g_hash_table_insert (type_cache, (gpointer) &builtin_types [i], (gpointer) &builtin_types [i]);
 }
 
 /**
@@ -1667,9 +1668,11 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
                                      const char *ptr, const char **rptr)
 {
        MonoGenericClass *gclass = g_new0 (MonoGenericClass, 1);
+       MonoGenericContainer *container;
        MonoGenericClass *cached;
        MonoGenericInst *ginst;
        MonoClass *gklass;
+       MonoType *gtype;
        int i, count;
 
        type->data.generic_class = gclass;
@@ -1679,11 +1682,10 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
 
        gclass->klass = g_new0 (MonoClass, 1);
 
-       gclass->generic_type = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
-
-       gklass = mono_class_from_mono_type (gclass->generic_type);
-       g_assert ((gclass->context->container = gclass->container = gklass->generic_container) != NULL);
+       gtype = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       gclass->container_class = gklass = mono_class_from_mono_type (gtype);
 
+       g_assert ((gclass->context->container = gklass->generic_container) != NULL);
        count = mono_metadata_decode_value (ptr, &ptr);
 
        /*
@@ -1754,7 +1756,12 @@ mono_metadata_parse_generic_param (MonoImage *m, MonoGenericContext *generic_con
                *rptr = ptr;
 
        g_assert (generic_context);
-       generic_container = generic_context->container;
+       if (generic_context->gmethod)
+               generic_container = generic_context->gmethod->container;
+       else if (generic_context->gclass)
+               generic_container = generic_context->gclass->container_class->generic_container;
+       else
+               generic_container = generic_context->container;
 
        if (!is_mvar) {
                g_assert (generic_container);
@@ -2696,11 +2703,9 @@ mono_type_size (MonoType *t, gint *align)
 
                g_assert (!gclass->inst->is_open && !gclass->klass->generic_container);
 
-               if (MONO_TYPE_ISSTRUCT (gclass->generic_type)) {
-                       MonoClass *gklass = mono_class_from_mono_type (gclass->generic_type);
-
-                       if (gklass->enumtype)
-                               return mono_type_size (gklass->enum_basetype, align);
+               if (gclass->container_class->valuetype) {
+                       if (gclass->container_class->enumtype)
+                               return mono_type_size (gclass->container_class->enum_basetype, align);
                        else
                                return mono_class_value_size (gclass->klass, align);
                } else {
@@ -2795,11 +2800,9 @@ mono_type_stack_size (MonoType *t, gint *align)
 
                g_assert (!gclass->inst->is_open && !gclass->klass->generic_container);
 
-               if (MONO_TYPE_ISSTRUCT (gclass->generic_type)) {
-                       MonoClass *gklass = mono_class_from_mono_type (gclass->generic_type);
-
-                       if (gklass->enumtype)
-                               return mono_type_stack_size (gklass->enum_basetype, align);
+               if (gclass->container_class->valuetype) {
+                       if (gclass->container_class->enumtype)
+                               return mono_type_stack_size (gclass->container_class->enum_basetype, align);
                        else {
                                guint32 size = mono_class_value_size (gclass->klass, align);
 
@@ -2825,17 +2828,17 @@ mono_type_stack_size (MonoType *t, gint *align)
 gboolean
 mono_metadata_generic_class_is_valuetype (MonoGenericClass *gclass)
 {
-       return MONO_TYPE_ISSTRUCT (gclass->generic_type);
+       return gclass->container_class->valuetype;
 }
 
 static gboolean
-_mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2, gboolean signature_only)
+_mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2, gboolean signature_only)
 {
        int i;
 
-       if (g1->inst->type_argc != g2->inst->type_argc)
+       if ((g1->inst->type_argc != g2->inst->type_argc) || (g1->is_dynamic != g2->is_dynamic))
                return FALSE;
-       if (!do_mono_metadata_type_equal (g1->generic_type, g2->generic_type, signature_only))
+       if (!mono_metadata_class_equal (g1->container_class, g2->container_class, signature_only))
                return FALSE;
        for (i = 0; i < g1->inst->type_argc; ++i) {
                if (!do_mono_metadata_type_equal (g1->inst->type_argv [i], g2->inst->type_argv [i], signature_only))
@@ -3783,12 +3786,13 @@ get_constraints (MonoImage *image, int owner, MonoGenericContext *context)
 }
 
 MonoGenericContainer *
-mono_metadata_load_generic_params (MonoImage *image, guint32 token)
+mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericContainer *parent_container)
 {
        MonoTableInfo *tdef  = &image->tables [MONO_TABLE_GENERICPARAM];
        guint32 cols [MONO_GENERICPARAM_SIZE];
        guint32 i, owner = 0, last_num, n;
        MonoGenericContainer *container;
+       MonoGenericClass *gclass;
        MonoGenericParam *params;
 
        if (mono_metadata_token_table (token) == MONO_TABLE_TYPEDEF)
@@ -3808,7 +3812,7 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token)
                if (cols [MONO_GENERICPARAM_OWNER] == owner)
                        break;
        }
-       last_num = 0;
+       last_num = i;
        if (i >= tdef->rows)
                return NULL;
        params = NULL;
@@ -3830,11 +3834,15 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token)
 
        container->type_argc = n;
        container->type_params = params;
+       container->parent = parent_container;
+
+       if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
+               container->is_method = 1;
 
        container->context.container = container;
 
        for (i = 0; i < n; i++)
-               params [i].constraints = get_constraints (image, i + 1, &container->context);
+               params [i].constraints = get_constraints (image, last_num + i + 1, &container->context);
 
        return container;
 }