2004-02-09 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / class.c
index 1b2011b9b4bc067e68457434b7db94b04f8cef0f..6b8d75728face562a7abdf015799acb7d0a052bf 100644 (file)
@@ -33,8 +33,6 @@
 #include <mono/metadata/reflection.h>
 #include <mono/os/gc_wrapper.h>
 
-#define CSIZE(x) (sizeof (x) / 4)
-
 MonoStats mono_stats;
 
 gboolean mono_print_vtable = FALSE;
@@ -201,29 +199,32 @@ mono_class_is_open_constructed_type (MonoType *t)
 }
 
 MonoType*
-mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst)
+mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst,
+                                MonoGenericMethod *gmethod)
 {
        switch (type->type) {
        case MONO_TYPE_MVAR:
-               if (ginst)
-                       return dup_type (ginst->type_argv [type->data.generic_param->num]);
+               if (gmethod && gmethod->mtype_argv)
+                       return dup_type (gmethod->mtype_argv [type->data.generic_param->num]);
                else
                        return type;
-       case MONO_TYPE_VAR: {
-               MonoType *t = ginst->type_argv [type->data.generic_param->num];
-
-               if ((t->type == MONO_TYPE_VAR) || (t->type == MONO_TYPE_MVAR))
+       case MONO_TYPE_VAR:
+               if (ginst) {
+                       MonoType *t = ginst->type_argv [type->data.generic_param->num];
+
+                       if ((t->type == MONO_TYPE_VAR) || (t->type == MONO_TYPE_MVAR))
+                               return type;
+                       else
+                               return dup_type (t);
+               } else
                        return type;
-               else
-                       return dup_type (t);
-       }
        case MONO_TYPE_SZARRAY: {
                MonoClass *eclass = type->data.klass;
                MonoClass *nclass;
                MonoType *nt;
-               if (eclass->byval_arg.type == MONO_TYPE_MVAR) {
-                       nclass = mono_class_from_mono_type (ginst->type_argv [eclass->byval_arg.data.generic_param->num]);
-               } else if (eclass->byval_arg.type == MONO_TYPE_VAR) {
+               if ((eclass->byval_arg.type == MONO_TYPE_MVAR) && gmethod) {
+                       nclass = mono_class_from_mono_type (gmethod->mtype_argv [eclass->byval_arg.data.generic_param->num]);
+               } else if ((eclass->byval_arg.type == MONO_TYPE_VAR) && ginst) {
                        nclass = mono_class_from_mono_type (ginst->type_argv [eclass->byval_arg.data.generic_param->num]);
                } else {
                        return type;
@@ -232,22 +233,44 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst)
                nt->data.klass = nclass;
                return nt;
        }
+       case MONO_TYPE_GENERICINST: {
+               MonoGenericInst *oginst = type->data.generic_inst;
+               MonoGenericInst *nginst;
+               MonoType *nt;
+               int i;
+
+               nginst = g_new0 (MonoGenericInst, 1);
+               *nginst = *oginst;
+
+               nginst->type_argv = g_new0 (MonoType *, oginst->type_argc);
+
+               for (i = 0; i < oginst->type_argc; i++) {
+                       MonoType *t = oginst->type_argv [i];
+                       nginst->type_argv [i] = mono_class_inflate_generic_type (t, ginst, gmethod);
+               };
+
+               nt = dup_type (type);
+               nt->data.generic_inst = nginst;
+               return nt;
+       }
        default:
                return type;
        }
        return type;
 }
 
-MonoMethodSignature*
-mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericInst *ginst)
+static MonoMethodSignature*
+inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig,
+                          MonoGenericMethod *gmethod)
 {
        MonoMethodSignature *res;
        int i;
        res = mono_metadata_signature_alloc (image, sig->param_count);
-       res->ret = mono_class_inflate_generic_type (sig->ret, ginst);
-       for (i = 0; i < sig->param_count; ++i) {
-               res->params [i] = mono_class_inflate_generic_type (sig->params [i], ginst);
-       }
+       res->ret = mono_class_inflate_generic_type (sig->ret, gmethod->generic_inst, gmethod);
+       for (i = 0; i < sig->param_count; ++i)
+               res->params [i] = mono_class_inflate_generic_type (sig->params [i],
+                                                                  gmethod->generic_inst,
+                                                                  gmethod);
        res->hasthis = sig->hasthis;
        res->explicit_this = sig->explicit_this;
        res->call_convention = sig->call_convention;
@@ -256,7 +279,7 @@ mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig
 }
 
 static MonoMethodHeader*
-inflate_generic_header (MonoMethodHeader *header, MonoGenericInst *ginst)
+inflate_generic_header (MonoMethodHeader *header, MonoGenericMethod *gmethod)
 {
        MonoMethodHeader *res;
        int i;
@@ -269,15 +292,16 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericInst *ginst)
        res->num_locals = header->num_locals;
        res->clauses = header->clauses;
        res->gen_params = header->gen_params;
-       res->geninst = ginst;
-       for (i = 0; i < header->num_locals; ++i) {
-               res->locals [i] = mono_class_inflate_generic_type (header->locals [i], ginst);
-       }
+       res->gen_method = gmethod;
+       for (i = 0; i < header->num_locals; ++i)
+               res->locals [i] = mono_class_inflate_generic_type (header->locals [i],
+                                                                  gmethod->generic_inst,
+                                                                  gmethod);
        return res;
 }
 
 MonoMethod*
-mono_class_inflate_generic_method (MonoMethod *method, MonoGenericInst *ginst)
+mono_class_inflate_generic_method (MonoMethod *method, MonoGenericMethod *gmethod)
 {
        MonoMethod *result;
        if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
@@ -289,11 +313,11 @@ mono_class_inflate_generic_method (MonoMethod *method, MonoGenericInst *ginst)
                *nmethod = *(MonoMethodNormal*)method;
                result = (MonoMethod*)nmethod;
                if (nmethod->header)
-                       nmethod->header = inflate_generic_header (nmethod->header, ginst);
+                       nmethod->header = inflate_generic_header (nmethod->header, gmethod);
        }
-       if (ginst->klass)
-               result->klass = ginst->klass;
-       result->signature = mono_class_inflate_generic_signature (method->klass->image, result->signature, ginst);
+       result->klass = gmethod->klass;
+       result->signature = inflate_generic_signature (
+               method->klass->image, result->signature, gmethod);
        return result;
 }
 
@@ -318,6 +342,7 @@ class_compute_field_layout (MonoClass *class)
        guint32 rva;
        guint32 packing_size = 0;
        gboolean explicit_size;
+       MonoClassField *field;
 
        if (class->size_inited)
                return;
@@ -360,46 +385,49 @@ class_compute_field_layout (MonoClass *class)
                guint32 cols [MONO_FIELD_SIZE];
                int idx = class->field.first + i;
 
-               mono_metadata_decode_row (t, idx, cols, CSIZE (cols));
+               field = &class->fields [i];
+               mono_metadata_decode_row (t, idx, cols, MONO_FIELD_SIZE);
                /* The name is needed for fieldrefs */
-               class->fields [i].name = mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]);
+               field->name = mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]);
                sig = mono_metadata_blob_heap (m, cols [MONO_FIELD_SIGNATURE]);
                mono_metadata_decode_value (sig, &sig);
                /* FIELD signature == 0x06 */
                g_assert (*sig == 0x06);
-               class->fields [i].type = mono_metadata_parse_field_type (
+               field->type = mono_metadata_parse_field_type (
                        m, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
+               if (mono_field_is_deleted (field))
+                       continue;
                if (class->generic_inst) {
-                       class->fields [i].type = mono_class_inflate_generic_type (class->fields [i].type, class->generic_inst->data.generic_inst);
-                       class->fields [i].type->attrs = cols [MONO_FIELD_FLAGS];
+                       field->type = mono_class_inflate_generic_type (field->type, class->generic_inst, NULL);
+                       field->type->attrs = cols [MONO_FIELD_FLAGS];
                }
 
-               class->fields [i].parent = class;
+               field->parent = class;
 
-               if (!(class->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC)) {
-                       if (class->fields [i].type->byref) {
+               if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
+                       if (field->type->byref) {
                                blittable = FALSE;
                        } else {
-                               MonoClass *field_class = mono_class_from_mono_type (class->fields [i].type);
+                               MonoClass *field_class = mono_class_from_mono_type (field->type);
                                if (!field_class || !field_class->blittable)
                                        blittable = FALSE;
                        }
                }
                if (layout == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) {
-                       mono_metadata_field_info (m, idx, &class->fields [i].offset, NULL, NULL);
-                       if (class->fields [i].offset == (guint32)-1)
-                               g_warning ("%s not initialized correctly (missing field layout info for %s)", class->name, class->fields [i].name);
+                       mono_metadata_field_info (m, idx, &field->offset, NULL, NULL);
+                       if (field->offset == (guint32)-1)
+                               g_warning ("%s not initialized correctly (missing field layout info for %s)", class->name, field->name);
                }
 
                if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
                        mono_metadata_field_info (m, idx, NULL, &rva, NULL);
                        if (!rva)
-                               g_warning ("field %s in %s should have RVA data, but hasn't", class->fields [i].name, class->name);
-                       class->fields [i].data = mono_cli_rva_map (class->image->image_info, rva);
+                               g_warning ("field %s in %s should have RVA data, but hasn't", field->name, class->name);
+                       field->data = mono_cli_rva_map (class->image->image_info, rva);
                }
 
                if (class->enumtype && !(cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_STATIC)) {
-                       class->enum_basetype = class->fields [i].type;
+                       class->enum_basetype = field->type;
                        class->cast_class = class->element_class = mono_class_from_mono_type (class->enum_basetype);
                        blittable = class->element_class->blittable;
                }
@@ -434,6 +462,7 @@ mono_class_layout_fields (MonoClass *class)
        guint32 layout = class->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
        guint32 pass, passes, real_size;
        gboolean gc_aware_layout = FALSE;
+       MonoClassField *field;
 
        /*
         * Enable GC aware auto layout: in this mode, reference
@@ -472,8 +501,11 @@ mono_class_layout_fields (MonoClass *class)
                for (pass = 0; pass < passes; ++pass) {
                        for (i = 0; i < top; i++){
                                int size, align;
+                               field = &class->fields [i];
 
-                               if (class->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC)
+                               if (mono_field_is_deleted (field))
+                                       continue;
+                               if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
                                        continue;
 
                                if (gc_aware_layout) {
@@ -484,7 +516,7 @@ mono_class_layout_fields (MonoClass *class)
                                         * some internal structures, we store GC_MALLOCed memory
                                         * in IntPtr fields...
                                         */
-                                       if (MONO_TYPE_IS_POINTER (class->fields [i].type)) {
+                                       if (MONO_TYPE_IS_POINTER (field->type)) {
                                                if (pass == 1)
                                                        continue;
                                        } else {
@@ -494,20 +526,20 @@ mono_class_layout_fields (MonoClass *class)
                                }
 
                                if ((top == 1) && (class->instance_size == sizeof (MonoObject)) &&
-                                       (strcmp (class->fields [i].name, "$PRIVATE$") == 0)) {
+                                       (strcmp (field->name, "$PRIVATE$") == 0)) {
                                        /* This field is a hack inserted by MCS to empty structures */
                                        continue;
                                }
 
-                               size = mono_type_size (class->fields [i].type, &align);
+                               size = mono_type_size (field->type, &align);
                        
                                /* FIXME (LAMESPEC): should we also change the min alignment according to pack? */
                                align = class->packing_size ? MIN (class->packing_size, align): align;
                                class->min_align = MAX (align, class->min_align);
-                               class->fields [i].offset = real_size;
-                               class->fields [i].offset += align - 1;
-                               class->fields [i].offset &= ~(align - 1);
-                               real_size = class->fields [i].offset + size;
+                               field->offset = real_size;
+                               field->offset += align - 1;
+                               field->offset &= ~(align - 1);
+                               real_size = field->offset + size;
                        }
 
                        class->instance_size = MAX (real_size, class->instance_size);
@@ -522,29 +554,32 @@ mono_class_layout_fields (MonoClass *class)
                real_size = 0;
                for (i = 0; i < top; i++) {
                        int size, align;
+                       field = &class->fields [i];
 
                        /*
                         * There must be info about all the fields in a type if it
                         * uses explicit layout.
                         */
 
-                       if (class->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC)
+                       if (mono_field_is_deleted (field))
+                               continue;
+                       if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
                                continue;
 
-                       size = mono_type_size (class->fields [i].type, &align);
+                       size = mono_type_size (field->type, &align);
                        
                        /*
-                        * When we get here, class->fields [i].offset is already set by the
+                        * When we get here, field->offset is already set by the
                         * loader (for either runtime fields or fields loaded from metadata).
                         * The offset is from the start of the object: this works for both
                         * classes and valuetypes.
                         */
-                       class->fields [i].offset += sizeof (MonoObject);
+                       field->offset += sizeof (MonoObject);
 
                        /*
                         * Calc max size.
                         */
-                       real_size = MAX (real_size, size + class->fields [i].offset);
+                       real_size = MAX (real_size, size + field->offset);
                }
                class->instance_size = MAX (real_size, class->instance_size);
                break;
@@ -557,15 +592,18 @@ mono_class_layout_fields (MonoClass *class)
         */
        for (i = 0; i < top; i++){
                int size, align;
+               field = &class->fields [i];
                        
-               if (!(class->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC))
+               if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
+                       continue;
+               if (mono_field_is_deleted (field))
                        continue;
                        
-               size = mono_type_size (class->fields [i].type, &align);
-               class->fields [i].offset = class->class_size;
-               class->fields [i].offset += align - 1;
-               class->fields [i].offset &= ~(align - 1);
-               class->class_size = class->fields [i].offset + size;
+               size = mono_type_size (field->type, &align);
+               field->offset = class->class_size;
+               field->offset += align - 1;
+               field->offset &= ~(align - 1);
+               class->class_size = field->offset + size;
        }
 }
 
@@ -935,6 +973,20 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
                                        if (im->flags & METHOD_ATTRIBUTE_STATIC)
                                                        continue;
                                        g_assert (io + l <= max_vtsize);
+
+                                       /* 
+                                        * If one of our parents already implements this interface
+                                        * we can inherit the implementation.
+                                        */
+                                       if (!(vtable [io + l])) {
+                                               MonoClass *parent = class->parent;
+
+                                               if ((ic->interface_id <= parent->max_interface_id) && 
+                                                       (parent->interface_offsets [ic->interface_id]) &&
+                                                       parent->vtable)
+                                                       vtable [io + l] = parent->vtable [parent->interface_offsets [ic->interface_id] + l];
+                                       }
+
                                        if (!(vtable [io + l])) {
                                                for (j = 0; j < onum; ++j) {
                                                        g_print (" at slot %d: %s (%d) overrides %s (%d)\n", io+l, overrides [j*2+1]->name, 
@@ -1558,7 +1610,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
        class->method.first = cols [MONO_TYPEDEF_METHOD_LIST] - 1;
 
        if (tt->rows > tidx){           
-               mono_metadata_decode_row (tt, tidx, cols_next, CSIZE (cols_next));
+               mono_metadata_decode_row (tt, tidx, cols_next, MONO_TYPEDEF_SIZE);
                class->field.last  = cols_next [MONO_TYPEDEF_FIELD_LIST] - 1;
                class->method.last = cols_next [MONO_TYPEDEF_METHOD_LIST] - 1;
        } else {
@@ -1621,99 +1673,75 @@ get_instantiation_name (const char *name, MonoGenericInst *ginst)
        return g_string_free (res, FALSE);
 }
 
-MonoClass*
-mono_class_create_from_generic (MonoImage *image, MonoType *gtype)
+static void
+mono_class_initialize_generic (MonoGenericInst *ginst, gboolean inflate_methods)
 {
-       MonoClass *gklass = mono_class_from_mono_type (gtype->data.generic_inst->generic_type);
-       MonoClass *class;
-
-       mono_class_init (gklass);
-
-       class = g_new0 (MonoClass, 1);
-       class->name_space = gklass->name_space;
-       class->image = image;
-       class->flags = gklass->flags;
-
-       class->generic_inst = gtype;
+       MonoClass *klass, *gklass, *pklass;
 
-       class->cast_class = class->element_class = class;
+       if (ginst->initialized || ginst->init_pending)
+               return;
 
-       return class;
-}
+       gklass = mono_class_from_mono_type (ginst->generic_type);
+       mono_class_init (gklass);
 
-void
-mono_class_initialize_generic (MonoClass *class, gboolean inflate_methods)
-{
-       MonoGenericInst *ginst = class->generic_inst->data.generic_inst;
-       MonoClass *gklass = mono_class_from_mono_type (ginst->generic_type);
+       klass = ginst->klass;
+       klass->name = get_instantiation_name (gklass->name, ginst);
 
-       if (class->name)
-               return;
+       if (ginst->parent)
+               pklass = mono_class_from_mono_type (ginst->parent);
+       else
+               pklass = gklass->parent;
 
-       class->name = get_instantiation_name (gklass->name, ginst);
+       mono_class_setup_parent (klass, pklass);
+       mono_class_setup_mono_type (klass);
 
        if (inflate_methods) {
                int i;
 
-               mono_class_setup_parent (class, gklass->parent);
-               mono_class_setup_mono_type (class);
+               klass->field = gklass->field;
+               klass->method = gklass->method;
+               klass->methods = g_new0 (MonoMethod *, klass->method.count);
+
+               for (i = 0; i < klass->method.count; i++) {
+                       MonoGenericMethod *gmethod = g_new0 (MonoGenericMethod, 1);
 
-               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);
+                       gmethod->klass = klass;
+                       gmethod->generic_method = gklass->methods [i];
+                       gmethod->generic_inst = ginst;
+
+                       klass->methods [i] = mono_class_inflate_generic_method (
+                               gklass->methods [i], gmethod);
+               }
        }
 
-       g_hash_table_insert (class->image->generics_cache, ginst->generic_type, class);
+       ginst->initialized = TRUE;
 }
 
 MonoClass*
-mono_class_from_generic (MonoType *gtype, gboolean inflate_methods)
+mono_class_from_generic (MonoGenericInst *ginst)
 {
-       MonoGenericInst *ginst = gtype->data.generic_inst;
-       MonoClass *gklass = mono_class_from_mono_type (ginst->generic_type);
-       MonoClass *class;
-       MonoImage *image;
+       MonoClass *class, *gklass, *pklass;
 
-       if (ginst->klass)
+       if (ginst->klass) {
+               mono_class_initialize_generic (ginst, TRUE);
                return ginst->klass;
+       }
 
        mono_loader_lock ();
 
-       image = gklass->image;
-       if ((class = g_hash_table_lookup (image->generics_cache, gtype))) {
-               mono_loader_unlock ();
-               return class;
-       }
-
+       gklass = mono_class_from_mono_type (ginst->generic_type);
        mono_class_init (gklass);
 
-       class = g_malloc0 (sizeof (MonoClass));
+       class = ginst->klass = g_malloc0 (sizeof (MonoClass));
        class->name_space = gklass->name_space;
        class->name = get_instantiation_name (gklass->name, ginst);
-       class->image = image;
+       class->image = gklass->image;
        class->flags = gklass->flags;
 
-       class->generic_inst = gtype;
+       class->generic_inst = ginst;
 
        class->cast_class = class->element_class = class;
 
-       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);
-       }
-
-       g_hash_table_insert (image->generics_cache, gtype, class);
-
        mono_loader_unlock ();
 
        return class;
@@ -1741,21 +1769,10 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb
                klass->parent = mono_defaults.object_class;
 
        if (count - pos > 0) {
-               int j;
-
                klass->interface_count = count - pos;
                klass->interfaces = g_new0 (MonoClass *, count - pos);
-               for (i = pos; i < count; i++) {
+               for (i = pos; i < count; i++)
                        klass->interfaces [i - pos] = param->constraints [i];
-                       klass->method.count += param->constraints [i]->method.count;
-               }
-
-               klass->methods = g_new0 (MonoMethod *, klass->method.count);
-               for (i = pos; i < count; i++) {
-                       MonoClass *iface = klass->interfaces [i - pos];
-                       for (j = 0; j < iface->method.count; j++)
-                               klass->methods [klass->method.last++] = iface->methods [j];
-               }
        }
 
        klass->name = g_strdup_printf (is_mvar ? "!!%d" : "!%d", param->num);
@@ -1763,7 +1780,7 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb
        klass->image = image;
        klass->cast_class = klass->element_class = klass;
        klass->enum_basetype = &klass->element_class->byval_arg;
-       klass->flags = TYPE_ATTRIBUTE_INTERFACE;
+       klass->flags = TYPE_ATTRIBUTE_INTERFACE | TYPE_ATTRIBUTE_PUBLIC;
 
        klass->this_arg.type = klass->byval_arg.type = is_mvar ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
        klass->this_arg.data.generic_param = klass->byval_arg.data.generic_param = param;
@@ -1789,7 +1806,7 @@ my_mono_class_from_generic_parameter (MonoGenericParam *param, gboolean is_mvar)
        klass->image = mono_defaults.corlib;
        klass->cast_class = klass->element_class = klass;
        klass->enum_basetype = &klass->element_class->byval_arg;
-       klass->flags = TYPE_ATTRIBUTE_INTERFACE;
+       klass->flags = TYPE_ATTRIBUTE_INTERFACE | TYPE_ATTRIBUTE_PUBLIC;
 
        klass->this_arg.type = klass->byval_arg.type = is_mvar ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
        klass->this_arg.data.generic_param = klass->byval_arg.data.generic_param = param;
@@ -1924,7 +1941,7 @@ mono_class_from_mono_type (MonoType *type)
        case MONO_TYPE_TYPEDBYREF:
                return type->data.klass? type->data.klass: mono_defaults.typed_reference_class;
        case MONO_TYPE_ARRAY:
-               return mono_array_class_get (type->data.array->eklass, type->data.array->rank);
+               return mono_bounded_array_class_get (type->data.array->eklass, type->data.array->rank, TRUE);
        case MONO_TYPE_PTR:
                return mono_ptr_class_get (type->data.type);
        case MONO_TYPE_FNPTR:
@@ -1935,7 +1952,7 @@ mono_class_from_mono_type (MonoType *type)
        case MONO_TYPE_VALUETYPE:
                return type->data.klass;
        case MONO_TYPE_GENERICINST:
-               return mono_class_from_generic (type, TRUE);
+               return mono_class_from_generic (type->data.generic_inst);
        case MONO_TYPE_VAR:
                return my_mono_class_from_generic_parameter (type->data.generic_param, FALSE);
        case MONO_TYPE_MVAR:
@@ -1970,6 +1987,9 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec)
        case MONO_TYPE_PTR:
                class = mono_class_from_mono_type (type->data.type);
                break;
+       case MONO_TYPE_GENERICINST:
+               class = mono_class_from_generic (type->data.generic_inst);
+               break;
        default:
                /* it seems any type can be stored in TypeSpec as well */
                class = mono_class_from_mono_type (type);
@@ -1980,15 +2000,16 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec)
 }
 
 /**
- * mono_array_class_get:
+ * mono_bounded_array_class_get:
  * @element_class: element class 
  * @rank: the dimension of the array class
+ * @bounded: whenever the array has non-zero bounds
  *
  * Returns: a class object describing the array with element type @element_type and 
  * dimension @rank. 
  */
 MonoClass *
-mono_array_class_get (MonoClass *eclass, guint32 rank)
+mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
 {
        MonoImage *image;
        MonoClass *class;
@@ -2000,6 +2021,10 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
 
        g_assert (rank <= 255);
 
+       if (rank > 1)
+               /* bounded only matters for one-dimensional arrays */
+               bounded = FALSE;
+
        image = eclass->image;
 
        mono_loader_lock ();
@@ -2007,7 +2032,7 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
        if ((rootlist = list = g_hash_table_lookup (image->array_cache, eclass))) {
                for (; list; list = list->next) {
                        class = list->data;
-                       if (class->rank == rank) {
+                       if ((class->rank == rank) && (class->byval_arg.type == (bounded ? MONO_TYPE_ARRAY : MONO_TYPE_SZARRAY))) {
                                mono_loader_unlock ();
                                return class;
                        }
@@ -2055,7 +2080,7 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
 
        class->element_class = eclass;
 
-       if (rank > 1) {
+       if ((rank > 1) || bounded) {
                MonoArrayType *at = g_new0 (MonoArrayType, 1);
                class->byval_arg.type = MONO_TYPE_ARRAY;
                class->byval_arg.data.array = at;
@@ -2063,7 +2088,6 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
                at->rank = rank;
                /* FIXME: complete.... */
        } else {
-               /* FIXME: this is not correct. the lbound could be >0 */
                class->byval_arg.type = MONO_TYPE_SZARRAY;
                class->byval_arg.data.klass = eclass;
        }
@@ -2081,6 +2105,20 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
        return class;
 }
 
+/**
+ * mono_array_class_get:
+ * @element_class: element class 
+ * @rank: the dimension of the array class
+ *
+ * Returns: a class object describing the array with element type @element_type and 
+ * dimension @rank. 
+ */
+MonoClass *
+mono_array_class_get (MonoClass *eclass, guint32 rank)
+{
+       return mono_bounded_array_class_get (eclass, rank, FALSE);
+}
+
 /**
  * mono_class_instance_size:
  * @klass: a class 
@@ -2233,9 +2271,9 @@ mono_class_get_property_from_name (MonoClass *klass, const char *name)
 MonoClass *
 mono_class_get (MonoImage *image, guint32 type_token)
 {
-       MonoClass *class;
+       MonoClass *class = NULL;
 
-       if (image->assembly->dynamic)
+       if (image->dynamic)
                return mono_lookup_dynamic_token (image, type_token);
 
        switch (type_token & 0xff000000){
@@ -2419,6 +2457,10 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
                        if (oklass->rank != klass->rank)
                                return FALSE;
 
+                       /* vectors vs. one dimensional arrays */
+                       if (oklass->byval_arg.type != klass->byval_arg.type)
+                               return FALSE;
+
                        eclass = klass->cast_class;
                        eoclass = oklass->cast_class;
 
@@ -2533,7 +2575,7 @@ mono_array_element_size (MonoClass *ac)
 gpointer
 mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class)
 {
-       if (image->assembly->dynamic) {
+       if (image->dynamic) {
                gpointer obj = mono_lookup_dynamic_token (image, token);
 
                switch (token & 0xff000000) {