grammar updates
[mono.git] / mono / metadata / metadata.c
index 5ec40545e09ec22570f89906b3d71388d9cdd9ed..0ee805fcc95f6e66015baf7158554294502f5e99 100644 (file)
@@ -35,7 +35,7 @@ static void do_mono_metadata_parse_type (MonoType *type, MonoImage *m, const cha
  * information might refer to different tables.
  */
 
-static MonoMetaTable AssemblySchema [] = {
+const static MonoMetaTable AssemblySchema [] = {
        { MONO_MT_UINT32,     "HashId" },
        { MONO_MT_UINT16,     "Major" },  
        { MONO_MT_UINT16,     "Minor" },
@@ -48,19 +48,19 @@ static MonoMetaTable AssemblySchema [] = {
        { MONO_MT_END, NULL }
 };
        
-static MonoMetaTable AssemblyOSSchema [] = {
+const static MonoMetaTable AssemblyOSSchema [] = {
        { MONO_MT_UINT32,     "OSPlatformID" },
        { MONO_MT_UINT32,     "OSMajor" },
        { MONO_MT_UINT32,     "OSMinor" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable AssemblyProcessorSchema [] = {
+const static MonoMetaTable AssemblyProcessorSchema [] = {
        { MONO_MT_UINT32,     "Processor" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable AssemblyRefSchema [] = {
+const static MonoMetaTable AssemblyRefSchema [] = {
        { MONO_MT_UINT16,     "Major" },
        { MONO_MT_UINT16,     "Minor" },
        { MONO_MT_UINT16,     "Build" },
@@ -73,7 +73,7 @@ static MonoMetaTable AssemblyRefSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable AssemblyRefOSSchema [] = {
+const static MonoMetaTable AssemblyRefOSSchema [] = {
        { MONO_MT_UINT32,     "OSPlatformID" },
        { MONO_MT_UINT32,     "OSMajorVersion" },
        { MONO_MT_UINT32,     "OSMinorVersion" },
@@ -81,20 +81,20 @@ static MonoMetaTable AssemblyRefOSSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable AssemblyRefProcessorSchema [] = {
+const static MonoMetaTable AssemblyRefProcessorSchema [] = {
        { MONO_MT_UINT32,     "Processor" },
        { MONO_MT_TABLE_IDX,  "AssemblyRef:AssemblyRef" },
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable ClassLayoutSchema [] = {
+const static MonoMetaTable ClassLayoutSchema [] = {
        { MONO_MT_UINT16,     "PackingSize" },
        { MONO_MT_UINT32,     "ClassSize" },
        { MONO_MT_TABLE_IDX,  "Parent:TypeDef" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable ConstantSchema [] = {
+const static MonoMetaTable ConstantSchema [] = {
        { MONO_MT_UINT8,      "Type" },
        { MONO_MT_UINT8,      "PaddingZero" },
        { MONO_MT_CONST_IDX,  "Parent" },
@@ -102,34 +102,34 @@ static MonoMetaTable ConstantSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable CustomAttributeSchema [] = {
+const static MonoMetaTable CustomAttributeSchema [] = {
        { MONO_MT_HASCAT_IDX, "Parent" },
        { MONO_MT_CAT_IDX,    "Type" },
        { MONO_MT_BLOB_IDX,   "Value" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable DeclSecuritySchema [] = {
+const static MonoMetaTable DeclSecuritySchema [] = {
        { MONO_MT_UINT16,     "Action" },
        { MONO_MT_HASDEC_IDX, "Parent" },
        { MONO_MT_BLOB_IDX,   "PermissionSet" },
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable EventMapSchema [] = {
+const static MonoMetaTable EventMapSchema [] = {
        { MONO_MT_TABLE_IDX,  "Parent:TypeDef" },
        { MONO_MT_TABLE_IDX,  "EventList:Event" },
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable EventSchema [] = {
+const static MonoMetaTable EventSchema [] = {
        { MONO_MT_UINT16,     "EventFlags#EventAttribute" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_TABLE_IDX,  "EventType" }, /* TypeDef or TypeRef */
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable ExportedTypeSchema [] = {
+const static MonoMetaTable ExportedTypeSchema [] = {
        { MONO_MT_UINT32,     "Flags" },
        { MONO_MT_TABLE_IDX,  "TypeDefId" },
        { MONO_MT_STRING_IDX, "TypeName" },
@@ -138,37 +138,37 @@ static MonoMetaTable ExportedTypeSchema [] = {
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable FieldSchema [] = {
+const static MonoMetaTable FieldSchema [] = {
        { MONO_MT_UINT16,     "Flags" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_BLOB_IDX,   "Signature" },
        { MONO_MT_END, NULL }   
 };
-static MonoMetaTable FieldLayoutSchema [] = {
+const static MonoMetaTable FieldLayoutSchema [] = {
        { MONO_MT_UINT32,     "Offset" },
        { MONO_MT_TABLE_IDX,  "Field:Field" },
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable FieldMarshalSchema [] = {
+const static MonoMetaTable FieldMarshalSchema [] = {
        { MONO_MT_HFM_IDX,    "Parent" },
        { MONO_MT_BLOB_IDX,   "NativeType" },
        { MONO_MT_END, NULL }   
 };
-static MonoMetaTable FieldRVASchema [] = {
+const static MonoMetaTable FieldRVASchema [] = {
        { MONO_MT_UINT32,     "RVA" },
        { MONO_MT_TABLE_IDX,  "Field:Field" },
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable FileSchema [] = {
+const static MonoMetaTable FileSchema [] = {
        { MONO_MT_UINT32,     "Flags" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_BLOB_IDX,   "Value" }, 
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable ImplMapSchema [] = {
+const static MonoMetaTable ImplMapSchema [] = {
        { MONO_MT_UINT16,     "MappingFlag" },
        { MONO_MT_MF_IDX,     "MemberForwarded" },
        { MONO_MT_STRING_IDX, "ImportName" },
@@ -176,13 +176,13 @@ static MonoMetaTable ImplMapSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable InterfaceImplSchema [] = {
+const static MonoMetaTable InterfaceImplSchema [] = {
        { MONO_MT_TABLE_IDX,  "Class:TypeDef" }, 
        { MONO_MT_TDOR_IDX,  "Interface=TypeDefOrRef" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable ManifestResourceSchema [] = {
+const static MonoMetaTable ManifestResourceSchema [] = {
        { MONO_MT_UINT32,     "Offset" },
        { MONO_MT_UINT32,     "Flags" },
        { MONO_MT_STRING_IDX, "Name" },
@@ -190,14 +190,14 @@ static MonoMetaTable ManifestResourceSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable MemberRefSchema [] = {
+const static MonoMetaTable MemberRefSchema [] = {
        { MONO_MT_MRP_IDX,    "Class" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_BLOB_IDX,   "Signature" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable MethodSchema [] = {
+const static MonoMetaTable MethodSchema [] = {
        { MONO_MT_UINT32,     "RVA" },
        { MONO_MT_UINT16,     "ImplFlags#MethodImplAttributes" },
        { MONO_MT_UINT16,     "Flags#MethodAttribute" },
@@ -207,21 +207,21 @@ static MonoMetaTable MethodSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable MethodImplSchema [] = {
+const static MonoMetaTable MethodImplSchema [] = {
        { MONO_MT_TABLE_IDX,  "Class:TypeDef" },
        { MONO_MT_MDOR_IDX,   "MethodBody" },
        { MONO_MT_MDOR_IDX,   "MethodDeclaration" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable MethodSemanticsSchema [] = {
+const static MonoMetaTable MethodSemanticsSchema [] = {
        { MONO_MT_UINT16,     "MethodSemantic" },
        { MONO_MT_TABLE_IDX,  "Method:Method" },
        { MONO_MT_HS_IDX,     "Association" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable ModuleSchema [] = {
+const static MonoMetaTable ModuleSchema [] = {
        { MONO_MT_UINT16,     "Generation" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_GUID_IDX,   "MVID" },
@@ -230,43 +230,43 @@ static MonoMetaTable ModuleSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable ModuleRefSchema [] = {
+const static MonoMetaTable ModuleRefSchema [] = {
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable NestedClassSchema [] = {
+const static MonoMetaTable NestedClassSchema [] = {
        { MONO_MT_TABLE_IDX,  "NestedClass:TypeDef" },
        { MONO_MT_TABLE_IDX,  "EnclosingClass:TypeDef" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable ParamSchema [] = {
+const static MonoMetaTable ParamSchema [] = {
        { MONO_MT_UINT16,     "Flags" },
        { MONO_MT_UINT16,     "Sequence" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable PropertySchema [] = {
+const static MonoMetaTable PropertySchema [] = {
        { MONO_MT_UINT16,     "Flags" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_BLOB_IDX,   "Type" },
        { MONO_MT_END, NULL }   
 };
 
-static MonoMetaTable PropertyMapSchema [] = {
+const static MonoMetaTable PropertyMapSchema [] = {
        { MONO_MT_TABLE_IDX,  "Parent:TypeDef" },
        { MONO_MT_TABLE_IDX,  "PropertyList:Property" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable StandaloneSigSchema [] = {
+const static MonoMetaTable StandaloneSigSchema [] = {
        { MONO_MT_BLOB_IDX,   "Signature" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable TypeDefSchema [] = {
+const static MonoMetaTable TypeDefSchema [] = {
        { MONO_MT_UINT32,     "Flags" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_STRING_IDX, "Namespace" },
@@ -276,20 +276,45 @@ static MonoMetaTable TypeDefSchema [] = {
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable TypeRefSchema [] = {
+const static MonoMetaTable TypeRefSchema [] = {
        { MONO_MT_RS_IDX,     "ResolutionScope=ResolutionScope" },
        { MONO_MT_STRING_IDX, "Name" },
        { MONO_MT_STRING_IDX, "Namespace" },
        { MONO_MT_END, NULL }
 };
 
-static MonoMetaTable TypeSpecSchema [] = {
+const static MonoMetaTable TypeSpecSchema [] = {
        { MONO_MT_BLOB_IDX,   "Signature" },
        { MONO_MT_END, NULL }
 };
 
-static struct {
-       MonoMetaTable *table;
+const static MonoMetaTable GenericParamSchema [] = {
+       { MONO_MT_UINT16,     "Number" },
+       { MONO_MT_UINT16,     "Flags" },
+       { MONO_MT_TABLE_IDX,  "Owner" }, /* TypeDef or MethodDef */
+       { MONO_MT_STRING_IDX, "Name" },
+
+       /* soon to be removed */
+       { MONO_MT_TABLE_IDX,  "Kind" }, 
+       { MONO_MT_TABLE_IDX,  "DeprecatedConstraint" },
+       
+       { MONO_MT_END, NULL }
+};
+
+const static MonoMetaTable MethodSpecSchema [] = {
+       { MONO_MT_MDOR_IDX,   "Method" },
+       { MONO_MT_BLOB_IDX,   "Signature" },
+       { MONO_MT_END, NULL }
+};
+
+const static MonoMetaTable GenericParamConstraintSchema [] = {
+       { MONO_MT_TABLE_IDX,  "GenericParam" },
+       { MONO_MT_TDOR_IDX,   "Constraint" },
+       { MONO_MT_END, NULL }
+};
+
+const static struct {
+       const MonoMetaTable *table;
        const char    *name;
 } tables [] = {
        /*  0 */ { ModuleSchema,               "Module" },
@@ -334,8 +359,9 @@ static struct {
        /* 27 */ { ExportedTypeSchema,         "ExportedType" },
        /* 28 */ { ManifestResourceSchema,     "ManifestResource" },
        /* 29 */ { NestedClassSchema,          "NestedClass" },
-       /* 2A */ { NULL,                       NULL },
-       /* 2B */ { NULL,                       NULL },
+       /* 2A */ { GenericParamSchema,         "GenericParam" },
+       /* 2B */ { MethodSpecSchema,           "MethodSpec" },
+       /* 2C */ { GenericParamConstraintSchema, "GenericParamConstraint" },
 };
 
 /**
@@ -347,7 +373,7 @@ static struct {
 const char *
 mono_meta_table_name (int table)
 {
-       if ((table < 0) || (table > 0x29))
+       if ((table < 0) || (table > 0x2c))
                return "";
        
        return tables [table].name;
@@ -386,7 +412,7 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
        int size = 0, field_size;
        int i, n, code;
        int shift = 0;
-       MonoMetaTable *table = tables [tableindex].table;
+       const MonoMetaTable *table = tables [tableindex].table;
 
        for (i = 0; (code = table [i].code) != MONO_MT_END; i++){
                switch (code){
@@ -435,7 +461,8 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                                break;
                        case MONO_TABLE_EXPORTEDTYPE:
                                g_assert (i == 1);
-                               field_size = idx_size (MONO_TABLE_TYPEDEF); break;
+                               /* the index is in another metadata file, so it must be 4 */
+                               field_size = 4; break;
                        case MONO_TABLE_FIELDLAYOUT:
                                g_assert (i == 1);
                                field_size = idx_size (MONO_TABLE_FIELD); break;
@@ -468,12 +495,26 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                        case MONO_TABLE_TYPEDEF:
                                g_assert (i == 4 || i == 5);
                                field_size = i == 4 ? idx_size (MONO_TABLE_FIELD):
-                                       idx_size(MONO_TABLE_METHOD); 
+                                       idx_size(MONO_TABLE_METHOD);
+                       case MONO_TABLE_GENERICPARAM:
+                               g_assert (i == 2 || i == 4 || i == 5);
+                               if (i == 2)
+                                       field_size = MAX (idx_size (MONO_TABLE_METHOD), idx_size (MONO_TABLE_TYPEDEF));
+                               else if (i == 4)
+                                       field_size = idx_size (MONO_TABLE_TYPEDEF);
+                               else if (i == 5)
+                                       field_size = idx_size (MONO_TABLE_TYPEDEF);
                                break;
+
+                       case MONO_TABLE_GENERICPARAMCONSTRAINT:
+                               g_assert (i == 0);
+                               field_size = idx_size (MONO_TABLE_GENERICPARAM);
+                               break;
+                               
                        default:
                                g_assert_not_reached ();
                        }
-                       if (field_size != idx_size (tableindex))
+                       if (tableindex != MONO_TABLE_EXPORTEDTYPE && field_size != idx_size (tableindex))
                                g_warning ("size changed (%d to %d)", idx_size (tableindex), field_size);
                        
                        break;
@@ -733,7 +774,7 @@ mono_metadata_locate_token (MonoImage *meta, guint32 token)
  *
  * Returns the MonoMetaTable structure for table @table
  */
-MonoMetaTable *
+const MonoMetaTable *
 mono_metadata_get_table (MonoMetaTableEnum table)
 {
        int x = (int) table;
@@ -804,7 +845,11 @@ mono_metadata_guid_heap (MonoImage *meta, guint32 index)
 static const char *
 dword_align (const char *ptr)
 {
+#if SIZEOF_VOID_P == 8
+       return (const char *) (((guint64) (ptr + 3)) & ~3);
+#else
        return (const char *) (((guint32) (ptr + 3)) & ~3);
+#endif
 }
 
 /**
@@ -989,7 +1034,7 @@ mono_metadata_parse_custom_mod (MonoImage *m, MonoCustomMod *dest, const char *p
                if (!dest)
                        dest = &local;
                dest->required = *ptr == MONO_TYPE_CMOD_REQD ? 1 : 0;
-               dest->token = mono_metadata_parse_typedef_or_ref (m, ptr + 1, &ptr);
+               dest->token = mono_metadata_parse_typedef_or_ref (m, ptr + 1, rptr);
                return TRUE;
        }
        return FALSE;
@@ -1011,8 +1056,10 @@ mono_metadata_parse_array (MonoImage *m, const char *ptr, const char **rptr)
 {
        int i;
        MonoArrayType *array = g_new0 (MonoArrayType, 1);
+       MonoType *etype;
        
-       array->type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       etype = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       array->eklass = mono_class_from_mono_type (etype);
        array->rank = mono_metadata_decode_value (ptr, &ptr);
 
        array->numsizes = mono_metadata_decode_value (ptr, &ptr);
@@ -1041,7 +1088,6 @@ mono_metadata_parse_array (MonoImage *m, const char *ptr, const char **rptr)
 void
 mono_metadata_free_array (MonoArrayType *array)
 {
-       mono_metadata_free_type (array->type);
        g_free (array->sizes);
        g_free (array->lobounds);
        g_free (array);
@@ -1091,8 +1137,6 @@ builtin_types[] = {
        {{NULL}, 0,     MONO_TYPE_I,       0,     1,     0},
        {{NULL}, 0,     MONO_TYPE_U,       0,     0,     0},
        {{NULL}, 0,     MONO_TYPE_U,       0,     1,     0},
-       {{NULL}, 0,     MONO_TYPE_OBJECT,  0,     0,     0},
-       {{NULL}, 0,     MONO_TYPE_OBJECT,  0,     1,     0}
 };
 
 #define NBUILTIN_TYPES() (sizeof (builtin_types) / sizeof (builtin_types [0]))
@@ -1121,6 +1165,22 @@ mono_type_equal (gconstpointer ka, gconstpointer kb)
        return 1;
 }
 
+/**
+ * mono_metadata_init:
+ *
+ *  Initialize the global variables of this module.
+ */
+void
+mono_metadata_init (void)
+{
+       int i;
+
+       type_cache = g_hash_table_new (mono_type_hash, mono_type_equal);
+
+       for (i = 0; i < NBUILTIN_TYPES (); ++i)
+               g_hash_table_insert (type_cache, &builtin_types [i], &builtin_types [i]);
+}
+
 /*
  * mono_metadata_parse_type:
  * @m: metadata context
@@ -1142,18 +1202,11 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
 {
        MonoType *type, *cached;
 
-       if (!type_cache) {
-               int i;
-               type_cache = g_hash_table_new (mono_type_hash, mono_type_equal);
-
-               for (i = 0; i < NBUILTIN_TYPES (); ++i)
-                       g_hash_table_insert (type_cache, &builtin_types [i], &builtin_types [i]);
-       }
-
        switch (mode) {
        case MONO_PARSE_MOD_TYPE:
        case MONO_PARSE_PARAM:
        case MONO_PARSE_RET:
+       case MONO_PARSE_LOCAL: /* should not have modifiers according to the spec, but ms tools disagree */
        case MONO_PARSE_FIELD: {
                /* count the modifiers */
                const char *tmp_ptr = ptr;
@@ -1161,7 +1214,7 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
                while (mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr))
                        count++;
                if (count) {
-                       type = g_malloc0 (sizeof (MonoType) + (count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
+                       type = g_malloc0 (sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
                        type->num_mods = count;
                        if (count > 64)
                                g_warning ("got more than 64 modifiers in type");
@@ -1172,7 +1225,6 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
                        break;
                } /* fall through */
        }
-       case MONO_PARSE_LOCAL:
        case MONO_PARSE_TYPE:
                /*
                 * Later we can avoid doing this allocation.
@@ -1209,6 +1261,8 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
        }
        if (rptr)
                *rptr = ptr;
+
+       /* No need to use locking since nobody is modifying the hash table */
        if (mode != MONO_PARSE_PARAM && !type->num_mods && (cached = g_hash_table_lookup (type_cache, type))) {
                mono_metadata_free_type (type);
                return cached;
@@ -1234,6 +1288,9 @@ mono_metadata_parse_signature (MonoImage *image, guint32 token)
        guint32 sig;
        const char *ptr;
 
+       if (image->assembly->dynamic)
+               return mono_lookup_dynamic_token (image, token);
+
        g_assert (mono_metadata_token_table(token) == MONO_TABLE_STANDALONESIG);
                
        sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
@@ -1244,10 +1301,22 @@ mono_metadata_parse_signature (MonoImage *image, guint32 token)
        return mono_metadata_parse_method_signature (image, FALSE, ptr, NULL); 
 }
 
+MonoMethodSignature*
+mono_metadata_signature_alloc (MonoImage *m, guint32 nparams)
+{
+       MonoMethodSignature *sig;
+
+       /* later we want to allocate signatures with mempools */
+       sig = g_malloc0 (sizeof (MonoMethodSignature) + ((gint32)nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+       sig->param_count = nparams;
+
+       return sig;
+}
+
 /*
  * mono_metadata_parse_method_signature:
  * @m: metadata context
- * @def: use #TRUE when parsing MethodDef, #FALSE with MethodRef signatures.
+ * @def: the MethodDef index or 0 for Ref signatures.
  * @ptr: pointer to the signature metadata representation
  * @rptr: pointer updated to match the end of the decoded stream
  *
@@ -1259,23 +1328,48 @@ MonoMethodSignature *
 mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, const char **rptr)
 {
        MonoMethodSignature *method;
-       int i;
+       int i, ret_attrs = 0, *pattrs = NULL;
        guint32 hasthis = 0, explicit_this = 0, call_convention, param_count;
+       guint32 gen_param_count = 0;
 
+       if (*ptr & 0x10)
+               gen_param_count = 1;
        if (*ptr & 0x20)
                hasthis = 1;
        if (*ptr & 0x40)
                explicit_this = 1;
        call_convention = *ptr & 0x0F;
        ptr++;
+       if (gen_param_count)
+               gen_param_count = mono_metadata_decode_value (ptr, &ptr);
        param_count = mono_metadata_decode_value (ptr, &ptr);
+       pattrs = g_new0 (int, param_count);
 
-       method = g_malloc0 (sizeof (MonoMethodSignature) + (param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
-       method->param_count = param_count;
+       if (def) {
+               MonoTableInfo *paramt = &m->tables [MONO_TABLE_PARAM];
+               MonoTableInfo *methodt = &m->tables [MONO_TABLE_METHOD];
+               guint32 cols [MONO_PARAM_SIZE];
+               guint lastp, param_index = mono_metadata_decode_row_col (methodt, def - 1, MONO_METHOD_PARAMLIST);
+
+               if (def < methodt->rows)
+                       lastp = mono_metadata_decode_row_col (methodt, def, MONO_METHOD_PARAMLIST);
+               else
+                       lastp = paramt->rows + 1;
+               for (i = param_index; i < lastp; ++i) {
+                       mono_metadata_decode_row (paramt, i - 1, cols, MONO_PARAM_SIZE);
+                       if (!cols [MONO_PARAM_SEQUENCE])
+                               ret_attrs = cols [MONO_PARAM_FLAGS];
+                       else
+                               pattrs [cols [MONO_PARAM_SEQUENCE] - 1] = cols [MONO_PARAM_FLAGS];
+               }
+       }
+       method = mono_metadata_signature_alloc (m, param_count);
        method->hasthis = hasthis;
        method->explicit_this = explicit_this;
        method->call_convention = call_convention;
-       method->ret = mono_metadata_parse_type (m, MONO_PARSE_RET, 0, ptr, &ptr);
+       method->generic_param_count = gen_param_count;
+       if (call_convention != 0xa)
+               method->ret = mono_metadata_parse_type (m, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
 
        if (method->param_count) {
                method->sentinelpos = -1;
@@ -1287,9 +1381,10 @@ mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, co
                                method->sentinelpos = i;
                                ptr++;
                        }
-                       method->params [i] = mono_metadata_parse_type (m, MONO_PARSE_PARAM, 0, ptr, &ptr);
+                       method->params [i] = mono_metadata_parse_type (m, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
                }
        }
+       g_free (pattrs);
 
        if (rptr)
                *rptr = ptr;
@@ -1316,6 +1411,48 @@ mono_metadata_free_method_signature (MonoMethodSignature *sig)
        g_free (sig);
 }
 
+static void
+do_mono_metadata_parse_generic_inst (MonoType *type, MonoImage *m, const char *ptr, const char **rptr)
+{
+       MonoGenericInst *generic_inst = g_new0 (MonoGenericInst, 1);
+       int i, count;
+
+       type->data.generic_inst = generic_inst;
+       
+       generic_inst->generic_type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       generic_inst->type_argc = count = mono_metadata_decode_value (ptr, &ptr);
+       generic_inst->type_argv = g_new0 (MonoType*, count);
+
+       /*
+        * Create the klass before parsing the type arguments.
+        * This is required to support "recursive" definitions.
+        * See mcs/tests/gen-23.cs for an example.
+        */
+
+       generic_inst->klass = mono_class_create_from_generic (m, type);
+
+       for (i = 0; i < generic_inst->type_argc; i++)
+               generic_inst->type_argv [i] = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       
+       mono_class_initialize_generic (generic_inst->klass, TRUE);
+       
+       if (rptr)
+               *rptr = ptr;
+}
+
+static MonoGenericParam *
+mono_metadata_parse_generic_param (MonoImage *m, const char *ptr, const char **rptr)
+{
+       MonoGenericParam *generic_param = g_new0 (MonoGenericParam, 1);
+       
+       generic_param->num = mono_metadata_decode_value (ptr, &ptr);
+
+       if (rptr)
+               *rptr = ptr;
+
+       return generic_param;
+}
+
 /* 
  * do_mono_metadata_parse_type:
  * @type: MonoType to be filled in with the return value
@@ -1362,7 +1499,11 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, const char *ptr, cons
                type->data.klass = mono_class_get (m, token);
                break;
        }
-       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_SZARRAY: {
+               MonoType *etype = mono_metadata_parse_type (m, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
+               type->data.klass = mono_class_from_mono_type (etype);
+               break;
+       }
        case MONO_TYPE_PTR:
                type->data.type = mono_metadata_parse_type (m, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
                break;
@@ -1372,8 +1513,18 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, const char *ptr, cons
        case MONO_TYPE_ARRAY:
                type->data.array = mono_metadata_parse_array (m, ptr, &ptr);
                break;
+
+       case MONO_TYPE_MVAR:
+       case MONO_TYPE_VAR:
+               type->data.generic_param = mono_metadata_parse_generic_param (m, ptr, &ptr);
+               break;
+
+       case MONO_TYPE_GENERICINST:
+               do_mono_metadata_parse_generic_inst (type, m, ptr, &ptr);
+               break;
+               
        default:
-               g_error ("type 0x%02x not handled in mono_metadata_parse_type", type->type);
+               g_error ("type 0x%02x not handled in do_mono_metadata_parse_type", type->type);
        }
        
        if (rptr)
@@ -1392,7 +1543,6 @@ mono_metadata_free_type (MonoType *type)
        if (type >= builtin_types && type < builtin_types + NBUILTIN_TYPES ())
                return;
        switch (type->type){
-       case MONO_TYPE_SZARRAY:
        case MONO_TYPE_PTR:
                mono_metadata_free_type (type->data.type);
                break;
@@ -1941,37 +2091,33 @@ mono_metadata_nested_in_typedef (MonoImage *meta, guint32 index)
  * @index: typedef token
  * 
  * Returns: the 1-based index into the TypeDef table of the first type
- * that is nested inside the type described by @index.
- * Retruns 0 if @index doesn't have nested types.
+ * that is nested inside the type described by @index. The search starts at
+ * @start_index.
+ * Returns 0 if no such type is found.
  */
 guint32
-mono_metadata_nesting_typedef (MonoImage *meta, guint32 index)
+mono_metadata_nesting_typedef (MonoImage *meta, guint32 index, guint32 start_index)
 {
        MonoTableInfo *tdef = &meta->tables [MONO_TABLE_NESTEDCLASS];
-       locator_t loc;
        guint32 start;
+       guint32 class_index = mono_metadata_token_index (index);
        
        if (!tdef->base)
                return 0;
 
-       loc.idx = mono_metadata_token_index (index);
-       loc.col_idx = MONO_NESTED_CLASS_ENCLOSING;
-       loc.t = tdef;
-
-       if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
-               return 0;
-
-       start = loc.result;
+       start = start_index;
 
-       while (start > 0) {
-               if (loc.idx == mono_metadata_decode_row_col (tdef, start - 1, MONO_NESTED_CLASS_ENCLOSING))
-                       start--;
-               else
+       while (start <= tdef->rows) {
+               if (class_index == mono_metadata_decode_row_col (tdef, start - 1, MONO_NESTED_CLASS_ENCLOSING))
                        break;
+               else
+                       start++;
        }
 
-       /* loc_result is 0..1, needs to be mapped to table index (that is +1) */
-       return start + 1;
+       if (start > tdef->rows)
+               return 0;
+       else
+               return start;
 }
 
 /*
@@ -2010,8 +2156,58 @@ mono_metadata_packing_from_typedef (MonoImage *meta, guint32 index, guint32 *pac
        return loc.result + 1;
 }
 
+/*
+ * mono_metadata_custom_attrs_from_index:
+ * @meta: metadata context
+ * @index: token representing the parent
+ * 
+ * Returns: the 1-based index into the CustomAttribute table of the first 
+ * attribute which belongs to the metadata object described by @index.
+ * Returns 0 if no such attribute is found.
+ */
+guint32
+mono_metadata_custom_attrs_from_index (MonoImage *meta, guint32 index)
+{
+       MonoTableInfo *tdef = &meta->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+       locator_t loc;
+       
+       if (!tdef->base)
+               return 0;
+
+       loc.idx = index;
+       loc.col_idx = MONO_CUSTOM_ATTR_PARENT;
+       loc.t = tdef;
+
+       if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
+               return 0;
+
+       /* Find the first entry by searching backwards */
+       while ((loc.result > 0) && (mono_metadata_decode_row_col (tdef, loc.result - 1, MONO_CUSTOM_ATTR_PARENT) == index))
+               loc.result --;
+
+       /* loc_result is 0..1, needs to be mapped to table index (that is +1) */
+       return loc.result + 1;
+}
+
+#ifdef DEBUG
+static void
+mono_backtrace (int limit)
+{
+       void *array[limit];
+       char **names;
+       int i;
+       backtrace (array, limit);
+       names = backtrace_symbols (array, limit);
+       for (i =0; i < limit; ++i) {
+               g_print ("\t%s\n", names [i]);
+       }
+       g_free (names);
+}
+#endif
+
 #ifndef __GNUC__
-#define __alignof__(a) sizeof(a)
+/*#define __alignof__(a) sizeof(a)*/
+#define __alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
 #endif
 
 /*
@@ -2059,6 +2255,7 @@ mono_type_size (MonoType *t, gint *align)
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
                *align = __alignof__(gint64);
+               return 8;               
        case MONO_TYPE_R8:
                *align = __alignof__(double);
                return 8;               
@@ -2083,11 +2280,20 @@ mono_type_size (MonoType *t, gint *align)
        case MONO_TYPE_PTR:
        case MONO_TYPE_FNPTR:
        case MONO_TYPE_ARRAY:
-       case MONO_TYPE_TYPEDBYREF: /* we may want to use a struct {MonoType* type, void *data } instead ...*/
+               *align = __alignof__(gpointer);
+               return sizeof (gpointer);
+       case MONO_TYPE_TYPEDBYREF:
+               return mono_class_value_size (mono_defaults.typed_reference_class, align);
+       case MONO_TYPE_GENERICINST: {
+               MonoClass *iclass = mono_class_from_mono_type (t);
+               return mono_type_size (&iclass->byval_arg, align);
+       }
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR:
                *align = __alignof__(gpointer);
                return sizeof (gpointer);
        default:
-               g_error ("type 0x%02x unknown", t->type);
+               g_error ("mono_type_size: type 0x%02x unknown", t->type);
        }
        return 0;
 }
@@ -2132,9 +2338,11 @@ mono_type_stack_size (MonoType *t, gint *align)
        case MONO_TYPE_PTR:
        case MONO_TYPE_FNPTR:
        case MONO_TYPE_ARRAY:
-       case MONO_TYPE_TYPEDBYREF:
                *align = __alignof__(gpointer);
                return sizeof (gpointer);
+       case MONO_TYPE_TYPEDBYREF:
+               *align = __alignof__(gpointer);
+               return sizeof (gpointer) * 2;
        case MONO_TYPE_R4:
                *align = __alignof__(float);
                return sizeof (float);          
@@ -2156,79 +2364,16 @@ mono_type_stack_size (MonoType *t, gint *align)
                        *align = *align + __alignof__(gpointer) - 1;
                        *align &= ~(__alignof__(gpointer) - 1);
 
-                       return size;
-               }
-       }
-       default:
-               g_error ("type 0x%02x unknown", t->type);
-       }
-       return 0;
-}
-
-/*
- * mono_type_native_stack_size:
- * @t: the type to return the size it uses on the stack
- *
- * Returns: the number of bytes required to hold an instance of this
- * type on the native stack
- */
-int
-mono_type_native_stack_size (MonoType *t, gint *align)
-{
-       int tmp;
-
-       g_assert (t != NULL);
-
-       if (!align)
-               align = &tmp;
+                       size += sizeof (gpointer) - 1;
+                       size &= ~(sizeof (gpointer) - 1);
 
-       if (t->byref) {
-               *align = 4;
-               return 4;
-       }
-
-       switch (t->type){
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_I1:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I2:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I:
-       case MONO_TYPE_U:
-       case MONO_TYPE_STRING:
-       case MONO_TYPE_OBJECT:
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_SZARRAY:
-       case MONO_TYPE_PTR:
-       case MONO_TYPE_FNPTR:
-       case MONO_TYPE_ARRAY:
-       case MONO_TYPE_TYPEDBYREF:
-               *align = 4;
-               return 4;
-       case MONO_TYPE_R4:
-               *align = 4;
-               return 4;
-       case MONO_TYPE_I8:
-       case MONO_TYPE_U8:
-       case MONO_TYPE_R8:
-               *align = 4;
-               return 8;
-       case MONO_TYPE_VALUETYPE: {
-               guint32 size;
-
-               if (t->data.klass->enumtype)
-                       return mono_type_native_stack_size (t->data.klass->enum_basetype, align);
-               else {
-                       size = mono_class_native_size (t->data.klass, align);
-                       *align = *align + 3;
-                       *align &= ~3;
-                       
                        return size;
                }
        }
+       case MONO_TYPE_GENERICINST: {
+               MonoClass *iclass = mono_class_from_mono_type (t);
+               return mono_type_stack_size (&iclass->byval_arg, align);
+       }
        default:
                g_error ("type 0x%02x unknown", t->type);
        }
@@ -2250,11 +2395,15 @@ mono_metadata_type_hash (MonoType *t1)
        switch (t1->type) {
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS:
+       case MONO_TYPE_SZARRAY:
                /* check if the distribution is good enough */
-               return hash << 7 | g_str_hash (t1->data.klass->name);
+               return ((hash << 5) - hash) ^ g_str_hash (t1->data.klass->name);
        case MONO_TYPE_PTR:
-       case MONO_TYPE_SZARRAY:
-               return hash << 7 | mono_metadata_type_hash (t1->data.type);
+               return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type);
+       case MONO_TYPE_ARRAY:
+               return ((hash << 5) - hash) ^ mono_metadata_type_hash (&t1->data.array->eklass->byval_arg);
+       case MONO_TYPE_GENERICINST:
+               return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.generic_inst->generic_type);
        }
        return hash;
 }
@@ -2292,17 +2441,33 @@ mono_metadata_type_equal (MonoType *t1, MonoType *t2)
        case MONO_TYPE_I:
        case MONO_TYPE_U:
        case MONO_TYPE_OBJECT:
+       case MONO_TYPE_TYPEDBYREF:
                return TRUE;
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS:
+       case MONO_TYPE_SZARRAY:
                return t1->data.klass == t2->data.klass;
        case MONO_TYPE_PTR:
-       case MONO_TYPE_SZARRAY:
                return mono_metadata_type_equal (t1->data.type, t2->data.type);
        case MONO_TYPE_ARRAY:
                if (t1->data.array->rank != t2->data.array->rank)
                        return FALSE;
-               return mono_metadata_type_equal (t1->data.array->type, t2->data.array->type);
+               return t1->data.array->eklass == t2->data.array->eklass;
+       case MONO_TYPE_GENERICINST: {
+               int i;
+               if (t1->data.generic_inst->type_argc != t2->data.generic_inst->type_argc)
+                       return FALSE;
+               if (!mono_metadata_type_equal (t1->data.generic_inst->generic_type, t2->data.generic_inst->generic_type))
+                       return FALSE;
+               for (i = 0; i < t1->data.generic_inst->type_argc; ++i) {
+                       if (!mono_metadata_type_equal (t1->data.generic_inst->type_argv [i], t2->data.generic_inst->type_argv [i]))
+                               return FALSE;
+               }
+               return TRUE;
+       }
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR:
+               return t1->data.generic_param->num == t2->data.generic_param->num;
        default:
                g_error ("implement type compare for %0x!", t1->type);
                return FALSE;
@@ -2333,8 +2498,8 @@ mono_metadata_signature_equal (MonoMethodSignature *sig1, MonoMethodSignature *s
                MonoType *p1 = sig1->params[i];
                MonoType *p2 = sig2->params[i];
                
-               if (p1->attrs != p2->attrs)
-                       return FALSE;
+               //if (p1->attrs != p2->attrs)
+               //      return FALSE;
                
                if (!mono_metadata_type_equal (p1, p2))
                        return FALSE;
@@ -2442,17 +2607,8 @@ mono_metadata_field_info (MonoImage *meta, guint32 index, guint32 *offset, guint
        if (marshal_spec) {
                const char *p;
                
-               tdef = &meta->tables [MONO_TABLE_FIELDMARSHAL];
-
-               loc.col_idx = MONO_FIELD_MARSHAL_PARENT;
-               loc.t = tdef;
-               loc.idx = (loc.idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_FIELDSREF;
-
-               if (tdef->base && bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator)) {
-                       p = mono_metadata_blob_heap (meta, mono_metadata_decode_row_col (tdef, loc.result, MONO_FIELD_MARSHAL_NATIVE_TYPE));
+               if ((p = mono_metadata_get_marshal_info (meta, index, TRUE))) {
                        *marshal_spec = mono_metadata_parse_marshal_spec (meta, p);
-               } else {
-                       *marshal_spec = NULL;
                }
        }
 
@@ -2712,12 +2868,31 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec)
        guint32 len;
        MonoType *type;
 
+       mono_loader_lock ();
+
+       if ((type = g_hash_table_lookup (image->typespec_cache, GUINT_TO_POINTER (type_spec)))) {
+               mono_loader_unlock ();
+               return type;
+       }
+
        t = &image->tables [MONO_TABLE_TYPESPEC];
        
        mono_metadata_decode_row (t, idx-1, cols, MONO_TYPESPEC_SIZE);
        ptr = mono_metadata_blob_heap (image, cols [MONO_TYPESPEC_SIGNATURE]);
        len = mono_metadata_decode_value (ptr, &ptr);
-       type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+
+       type = g_new0 (MonoType, 1);
+
+       g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER (type_spec), type);
+
+       if (*ptr == MONO_TYPE_BYREF) {
+               type->byref = 1; 
+               ptr++;
+       }
+
+       do_mono_metadata_parse_type (type, image, ptr, &ptr);
+
+       mono_loader_unlock ();
 
        return type;
 }
@@ -2738,21 +2913,37 @@ mono_metadata_parse_marshal_spec (MonoImage *image, const char *ptr)
 
        if (res->native == MONO_NATIVE_LPARRAY) {
                if (ptr - start <= len)
-                       res->elem_type = *ptr++;
+                       res->data.array_data.elem_type = *ptr++;
                if (ptr - start <= len)
-                       res->param_num = mono_metadata_decode_value (ptr, &ptr);
+                       res->data.array_data.param_num = mono_metadata_decode_value (ptr, &ptr);
                if (ptr - start <= len)
-                       res->num_elem = mono_metadata_decode_value (ptr, &ptr);
+                       res->data.array_data.num_elem = mono_metadata_decode_value (ptr, &ptr);
        } 
 
        if (res->native == MONO_NATIVE_BYVALTSTR) {
                if (ptr - start <= len)
-                       res->num_elem = mono_metadata_decode_value (ptr, &ptr);
+                       res->data.array_data.num_elem = mono_metadata_decode_value (ptr, &ptr);
        }
 
        if (res->native == MONO_NATIVE_BYVALARRAY) {
                if (ptr - start <= len)
-                       res->num_elem = mono_metadata_decode_value (ptr, &ptr);
+                       res->data.array_data.num_elem = mono_metadata_decode_value (ptr, &ptr);
+       }
+       
+       if (res->native == MONO_NATIVE_CUSTOM) {
+               /* skip unused type guid */
+               len = mono_metadata_decode_value (ptr, &ptr);
+               ptr += len;
+               /* skip unused native type name */
+               len = mono_metadata_decode_value (ptr, &ptr);
+               ptr += len;
+               /* read custom marshaler type name */
+               len = mono_metadata_decode_value (ptr, &ptr);
+               res->data.custom_data.custom_name = g_strndup (ptr, len);               
+               ptr += len;
+               /* read cookie string */
+               len = mono_metadata_decode_value (ptr, &ptr);
+               res->data.custom_data.cookie = g_strndup (ptr, len);
        }
 
        return res;
@@ -2784,8 +2975,9 @@ handle_enum:
                        case MONO_NATIVE_BOOLEAN:
                                *conv = MONO_MARSHAL_CONV_BOOL_I4;
                                return MONO_NATIVE_BOOLEAN;
+                       case MONO_NATIVE_I1:
                        case MONO_NATIVE_U1:
-                               return MONO_NATIVE_U1;
+                               return mspec->native;
                        default:
                                g_error ("cant marshal bool to native type %02x", mspec->native);
                        }
@@ -2885,6 +3077,12 @@ handle_enum:
                                g_error ("cant marshal object as native type %02x", mspec->native);
                        }
                }
+               if (t == MONO_TYPE_CLASS && (type->data.klass == mono_defaults.multicastdelegate_class ||
+                                            type->data.klass == mono_defaults.delegate_class || 
+                                            type->data.klass->parent == mono_defaults.multicastdelegate_class)) {
+                       *conv = MONO_MARSHAL_CONV_DEL_FTN;
+                       return MONO_NATIVE_FUNC;
+               }
                *conv = MONO_MARSHAL_CONV_OBJECT_STRUCT;
                return MONO_NATIVE_STRUCT;
        }
@@ -2896,86 +3094,6 @@ handle_enum:
        return MONO_NATIVE_MAX;
 }
 
-gint32
-mono_marshal_type_size (MonoType *type, MonoMarshalSpec *mspec, gint32 *align, 
-                       gboolean as_field, gboolean unicode)
-{
-       MonoMarshalNative native_type = mono_type_to_unmanaged (type, mspec, as_field, unicode, NULL);
-       MonoClass *klass;
-
-       switch (native_type) {
-       case MONO_NATIVE_BOOLEAN:
-               *align = 4;
-               return 4;
-       case MONO_NATIVE_I1:
-       case MONO_NATIVE_U1:
-               *align = 1;
-               return 1;
-       case MONO_NATIVE_I2:
-       case MONO_NATIVE_U2:
-               *align = 2;
-               return 2;
-       case MONO_NATIVE_I4:
-       case MONO_NATIVE_U4:
-       case MONO_NATIVE_ERROR:
-               *align = 4;
-               return 4;
-       case MONO_NATIVE_I8:
-       case MONO_NATIVE_U8:
-               *align = 4;
-               return 8;
-       case MONO_NATIVE_R4:
-               *align = 4;
-               return 4;
-       case MONO_NATIVE_R8:
-               *align = 4;
-               return 8;
-       case MONO_NATIVE_INT:
-       case MONO_NATIVE_UINT:
-       case MONO_NATIVE_LPSTR:
-       case MONO_NATIVE_LPWSTR:
-       case MONO_NATIVE_LPTSTR:
-       case MONO_NATIVE_BSTR:
-       case MONO_NATIVE_ANSIBSTR:
-       case MONO_NATIVE_TBSTR:
-       case MONO_NATIVE_LPARRAY:
-       case MONO_NATIVE_SAFEARRAY:
-       case MONO_NATIVE_IUNKNOWN:
-       case MONO_NATIVE_IDISPATCH:
-       case MONO_NATIVE_INTERFACE:
-       case MONO_NATIVE_ASANY:
-       case MONO_NATIVE_VARIANTBOOL:
-       case MONO_NATIVE_FUNC:
-       case MONO_NATIVE_LPSTRUCT:
-               *align =  4;
-               return sizeof (gpointer);
-       case MONO_NATIVE_STRUCT: 
-               klass = mono_class_from_mono_type (type);
-               return mono_class_native_size (klass, align);
-       case MONO_NATIVE_BYVALTSTR: {
-               int esize = unicode ? 2: 1;
-               g_assert (mspec);
-               *align = esize;
-               return mspec->num_elem * esize;
-       }
-       case MONO_NATIVE_BYVALARRAY: {
-               int esize;
-               klass = mono_class_from_mono_type (type);
-               esize = mono_class_native_size (klass->element_class, align);
-               g_assert (mspec);
-               return mspec->num_elem * esize;
-       }
-       case MONO_NATIVE_CURRENCY:
-       case MONO_NATIVE_VBBYREFSTR:
-       case MONO_NATIVE_CUSTOM:
-       default:
-               g_error ("native type %02x not implemented", native_type); 
-               break;
-       }
-       g_assert_not_reached ();
-       return 0;
-}
-
 const char*
 mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field)
 {
@@ -2995,3 +3113,170 @@ mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field)
        return mono_metadata_blob_heap (meta, mono_metadata_decode_row_col (tdef, loc.result, MONO_FIELD_MARSHAL_NATIVE_TYPE));
 }
 
+static MonoMethod*
+method_from_method_def_or_ref (MonoImage *m, guint32 tok)
+{
+       guint32 idx = tok >> METHODDEFORREF_BITS;
+       switch (tok & METHODDEFORREF_MASK) {
+       case METHODDEFORREF_METHODDEF:
+               return mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
+       case METHODDEFORREF_METHODREF:
+               return mono_get_method (m, MONO_TOKEN_MEMBER_REF | idx, NULL);
+       }
+       g_assert_not_reached ();
+       return NULL;
+}
+
+MonoMethod**
+mono_class_get_overrides (MonoImage *image, guint32 type_token, gint32 *num_overrides)
+{
+       locator_t loc;
+       MonoTableInfo *tdef  = &image->tables [MONO_TABLE_METHODIMPL];
+       guint32 start, end;
+       gint32 i, num;
+       guint32 cols [MONO_METHODIMPL_SIZE];
+       MonoMethod **result;
+
+       if (num_overrides)
+               *num_overrides = 0;
+
+       if (!tdef->base)
+               return NULL;
+
+       loc.t = tdef;
+       loc.col_idx = MONO_METHODIMPL_CLASS;
+       loc.idx = mono_metadata_token_index (type_token);
+
+       if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
+               return NULL;
+
+       start = loc.result;
+       end = start + 1;
+       /*
+        * We may end up in the middle of the rows... 
+        */
+       while (start > 0) {
+               if (loc.idx == mono_metadata_decode_row_col (tdef, start - 1, MONO_METHODIMPL_CLASS))
+                       start--;
+               else
+                       break;
+       }
+       while (end < tdef->rows) {
+               if (loc.idx == mono_metadata_decode_row_col (tdef, end, MONO_METHODIMPL_CLASS))
+                       end++;
+               else
+                       break;
+       }
+       num = end - start;
+       result = g_new (MonoMethod*, num * 2);
+       for (i = 0; i < num; ++i) {
+               mono_metadata_decode_row (tdef, start + i, cols, MONO_METHODIMPL_SIZE);
+               result [i * 2] = method_from_method_def_or_ref (image, cols [MONO_METHODIMPL_DECLARATION]);
+               result [i * 2 + 1] = method_from_method_def_or_ref (image, cols [MONO_METHODIMPL_BODY]);
+       }
+
+       if (num_overrides)
+               *num_overrides = num;
+       return result;
+}
+
+/**
+ * mono_guid_to_string:
+ *
+ * Converts a 16 byte Microsoft GUID to the standard string representation.
+ */
+char *
+mono_guid_to_string (const guint8 *guid)
+{
+       return g_strdup_printf ("%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", 
+                               guid[3], guid[2], guid[1], guid[0],
+                               guid[5], guid[4],
+                               guid[7], guid[6],
+                               guid[8], guid[9],
+                               guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
+}
+
+static MonoClass**
+get_constraints (MonoImage *image, int owner)
+{
+       MonoTableInfo *tdef  = &image->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
+       guint32 cols [MONO_GENPARCONSTRAINT_SIZE];
+       guint32 i, token, found;
+       MonoClass *klass, **res;
+       GList *cons = NULL, *tmp;
+       
+
+       found = 0;
+       for (i = 0; i < tdef->rows; ++i) {
+               mono_metadata_decode_row (tdef, i, cols, MONO_GENPARCONSTRAINT_SIZE);
+               if (cols [MONO_GENPARCONSTRAINT_GENERICPAR] == owner) {
+                       token = mono_metadata_token_from_dor (cols [MONO_GENPARCONSTRAINT_CONSTRAINT]);
+                       klass = mono_class_get (image, token);
+                       cons = g_list_append (cons, klass);
+                       ++found;
+               } else {
+                       /* contiguous list finished */
+                       if (found)
+                               break;
+               }
+       }
+       if (!found)
+               return NULL;
+       res = g_new0 (MonoClass*, found + 1);
+       for (i = 0, tmp = cons; i < found; ++i, tmp = tmp->next) {
+               res [i] = tmp->data;
+       }
+       g_list_free (cons);
+       return res;
+}
+
+MonoGenericParam *
+mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num)
+{
+       MonoTableInfo *tdef  = &image->tables [MONO_TABLE_GENERICPARAM];
+       guint32 cols [MONO_GENERICPARAM_SIZE];
+       guint32 i, owner, last_num, n;
+       MonoGenericParam *params;
+
+       if (mono_metadata_token_table (token) == MONO_TABLE_TYPEDEF)
+               owner = MONO_TYPEORMETHOD_TYPE;
+       else if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
+               owner = MONO_TYPEORMETHOD_METHOD;
+       else {
+               g_error ("wrong token %x to load_generics_params", token);
+       }
+       owner |= mono_metadata_token_index (token) << MONO_TYPEORMETHOD_BITS;
+       if (num)
+               *num = 0;
+       if (!tdef->base)
+               return NULL;
+
+       for (i = 0; i < tdef->rows; ++i) {
+               mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
+               if (cols [MONO_GENERICPARAM_OWNER] == owner)
+                       break;
+       }
+       last_num = 0;
+       if (i >= tdef->rows)
+               return NULL;
+       params = NULL;
+       n = 1;
+       do {
+               params = g_realloc (params, sizeof (MonoGenericParam) * n);
+               params [n - 1].pklass = NULL;
+               params [n - 1].method = NULL;
+               params [n - 1].flags = cols [MONO_GENERICPARAM_FLAGS];
+               params [n - 1].num = cols [MONO_GENERICPARAM_NUMBER];
+               params [n - 1].name = mono_metadata_string_heap (image, cols [MONO_GENERICPARAM_NAME]);
+               params [n - 1].constraints = get_constraints (image, i + 1);
+               if (++i >= tdef->rows)
+                       break;
+               mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
+               n++;
+       } while (cols [MONO_GENERICPARAM_OWNER] == owner);
+       
+       if (num)
+               *num = n;
+       return params;
+}
+