Wed Aug 14 17:26:27 CEST 2002 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / class.c
index 1d0d7b813714ce7a579baf09db8d0c049d682213..b2129af584c42544fb81810fec770fe08a8a1e31 100644 (file)
@@ -189,6 +189,35 @@ class_compute_field_layout (MonoClass *class)
        MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
        int i, blittable = TRUE;
        guint32 rva;
+       guint32 packing_size = 0;
+
+       if (class->size_inited)
+               return;
+
+       if (class->parent) {
+               if (!class->parent->size_inited)
+                       class_compute_field_layout (class->parent);
+               class->instance_size += class->parent->instance_size;
+               class->class_size += class->parent->class_size;
+               class->min_align = class->parent->min_align;
+       } else {
+               class->instance_size = sizeof (MonoObject);
+               class->min_align = 1;
+       }
+
+       if (mono_metadata_packing_from_typedef (class->image, class->type_token, &packing_size, &class->instance_size)) {
+               class->instance_size += sizeof (MonoObject);
+       }
+
+       g_assert ((packing_size & 0xfffffff0) == 0);
+       class->packing_size = packing_size;
+
+       if (!top) {
+               class->size_inited = 1;
+               return;
+       }
+
+       class->fields = g_new0 (MonoClassField, top);
 
        /*
         * Fetch all the field information.
@@ -772,7 +801,6 @@ mono_class_init (MonoClass *class)
        static MonoMethod *default_finalize = NULL;
        static int finalize_slot = -1;
        static int ghc_slot = -1;
-       guint32 packing_size = 0;
 
        g_assert (class);
 
@@ -788,29 +816,14 @@ mono_class_init (MonoClass *class)
 
        mono_stats.initialized_class_count++;
 
-       if (class->parent) {
-               if (!class->parent->inited)
-                       mono_class_init (class->parent);
-               class->instance_size += class->parent->instance_size;
-               class->class_size += class->parent->class_size;
-               class->min_align = class->parent->min_align;
-       } else
-               class->min_align = 1;
-
-       if (mono_metadata_packing_from_typedef (class->image, class->type_token, &packing_size, &class->instance_size)) {
-               class->instance_size += sizeof (MonoObject);
-       }
-
-       g_assert ((packing_size & 0xfffffff0) == 0);
-       class->packing_size = packing_size;
+       if (class->parent && !class->parent->inited)
+               mono_class_init (class->parent);
 
        /*
         * Computes the size used by the fields, and their locations
         */
-       if (!class->size_inited && class->field.count > 0){
-               class->fields = g_new0 (MonoClassField, class->field.count);
+       if (!class->size_inited)
                class_compute_field_layout (class);
-       }
 
        /* initialize method pointers */
        class->methods = g_new (MonoMethod*, class->method.count);
@@ -1097,7 +1110,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
        guint icount = 0; 
        MonoClass **interfaces;
 
-       if ((class = g_hash_table_lookup (image->class_cache, GUINT_TO_POINTER (type_token))))
+       if ((class = g_hash_table_lookup (image->class_cache, GUINT_TO_POINTER (type_token)))) 
                return class;
 
        g_assert (mono_metadata_token_table (type_token) == MONO_TABLE_TYPEDEF);
@@ -1177,10 +1190,8 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 
        /*class->interfaces = mono_metadata_interfaces_from_typedef (image, type_token, &class->interface_count); */
 
-       if (class->enumtype) {
-               class->fields = g_new0 (MonoClassField, class->field.count);
+       if (class->enumtype)
                class_compute_field_layout (class);
-       } 
 
        if ((type_token = mono_metadata_nested_in_typedef (image, type_token)))
                class->nested_in = mono_class_create_from_typedef (image, type_token);
@@ -1328,7 +1339,7 @@ mono_array_class_get (MonoType *element_type, guint32 rank)
        MonoClass *class;
        MonoClass *parent = NULL;
        GSList *list;
-       int rnum = 0;
+       int rnum = 0, nsize;
 
        eclass = mono_class_from_mono_type (element_type);
        g_assert (rank <= 255);
@@ -1351,8 +1362,15 @@ mono_array_class_get (MonoType *element_type, guint32 rank)
        class = g_malloc0 (sizeof (MonoClass) + parent->vtable_size * sizeof (gpointer));
 
        class->image = image;
-       class->name_space = "System";
-       class->name = "Array";
+       class->name_space = eclass->name_space;
+       nsize = strlen (eclass->name);
+       class->name = g_malloc (nsize + 2 + rank);
+       memcpy (class->name, eclass->name, nsize);
+       class->name [nsize] = '[';
+       if (rank > 1)
+               memset (class->name + nsize + 1, ',', rank - 1);
+       class->name [nsize + rank] = ']';
+       class->name [nsize + rank + 1] = 0;
        class->type_token = 0;
        class->flags = TYPE_ATTRIBUTE_CLASS;
        class->parent = parent;
@@ -1523,9 +1541,27 @@ mono_class_get_field_from_name (MonoClass *klass, const char *name)
 {
        int i;
 
-       for (i = 0; i < klass->field.count; ++i) {
-               if (strcmp (name, klass->fields [i].name) == 0)
-                       return &klass->fields [i];
+       while (klass) {
+               for (i = 0; i < klass->field.count; ++i) {
+                       if (strcmp (name, klass->fields [i].name) == 0)
+                               return &klass->fields [i];
+               }
+               klass = klass->parent;
+       }
+       return NULL;
+}
+
+MonoProperty*
+mono_class_get_property_from_name (MonoClass *klass, const char *name)
+{
+       int i;
+
+       while (klass) {
+               for (i = 0; i < klass->property.count; ++i) {
+                       if (strcmp (name, klass->properties [i].name) == 0)
+                               return &klass->properties [i];
+               }
+               klass = klass->parent;
        }
        return NULL;
 }