This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mono / metadata / metadata.c
index 628fa4d7a98d718e86a07b6f74c6b851c1f197e4..3d44463cde90be1fab9068944735fdeb6b6dd1ab 100644 (file)
@@ -17,6 +17,8 @@
 #include "mono-endian.h"
 #include "cil-coff.h"
 #include "tokentype.h"
+#include "metadata-internals.h"
+#include "class-internals.h"
 #include "private.h"
 #include "class.h"
 
@@ -296,7 +298,6 @@ const static MonoMetaTable GenericParamSchema [] = {
 
        /* soon to be removed */
        { MONO_MT_TABLE_IDX,  "Kind" }, 
-       { MONO_MT_TABLE_IDX,  "DeprecatedConstraint" },
        
        { MONO_MT_END, NULL }
 };
@@ -1201,64 +1202,84 @@ MonoType*
 mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs, const char *ptr, const char **rptr)
 {
        MonoType *type, *cached;
+       gboolean byref = FALSE;
+       gboolean pinned = FALSE;
+       const char *tmp_ptr;
+       int count = 0;
+       gboolean found;
 
-       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;
-               int count = 0;
-               while (mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr))
-                       count++;
-               if (count) {
-                       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");
-                       /* save them this time */
-                       count = 0;
-                       while (mono_metadata_parse_custom_mod (m, &(type->modifiers [count]), ptr, &ptr))
-                               count++;
+       /*
+        * According to the spec, custom modifiers should come before the byref
+        * flag, but the IL produced by ilasm from the following signature:
+        *   object modopt(...) &
+        * starts with a byref flag, followed by the modifiers. (bug #49802)
+        * Also, this type seems to be different from 'object & modopt(...)'. Maybe
+        * it would be better to treat byref as real type constructor instead of
+        * a modifier...
+        * Also, pinned should come before anything else, but some MSV++ produced
+        * assemblies violate this (#bug 61990).
+        */
+
+       /* Count the modifiers first */
+       tmp_ptr = ptr;
+       found = TRUE;
+       while (found) {
+               switch (*tmp_ptr) {
+               case MONO_TYPE_PINNED:
+               case MONO_TYPE_BYREF:
+                       ++tmp_ptr;
                        break;
-               } /* fall through */
+               case MONO_TYPE_CMOD_REQD:
+               case MONO_TYPE_CMOD_OPT:
+                       count ++;
+                       mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr);
+                       break;
+               default:
+                       found = FALSE;
+               }
        }
-       case MONO_PARSE_TYPE:
+
+       if (count) {
+               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");
+       }
+       else
                /*
                 * Later we can avoid doing this allocation.
                 */
                type = g_new0 (MonoType, 1);
-               break;
-       default:
-               g_assert_not_reached ();
-       }
-       
-       type->attrs = opt_attrs;
-       if (mode == MONO_PARSE_LOCAL) {
-               /*
-                * check for pinned flag
-                */
-               if (*ptr == MONO_TYPE_PINNED) {
-                       type->pinned = 1;
+
+       /* Parse pinned, byref and custom modifiers */
+       found = TRUE;
+       count = 0;
+       while (found) {
+               switch (*ptr) {
+               case MONO_TYPE_PINNED:
+                       pinned = TRUE;
                        ++ptr;
+                       break;
+               case MONO_TYPE_BYREF:
+                       byref = TRUE;
+                       ++ptr;
+                       break;
+               case MONO_TYPE_CMOD_REQD:
+               case MONO_TYPE_CMOD_OPT:
+                       count ++;
+                       mono_metadata_parse_custom_mod (m, &(type->modifiers [count]), ptr, &ptr);
+                       break;
+               default:
+                       found = FALSE;
                }
        }
+       
+       type->attrs = opt_attrs;
+       type->byref = byref;
+       type->pinned = pinned ? 1 : 0;
+
+       do_mono_metadata_parse_type (type, m, ptr, &ptr);
 
-       switch (*ptr) {
-       case MONO_TYPE_BYREF: 
-               if (mode == MONO_PARSE_FIELD)
-                       g_warning ("A field type cannot be byref");
-               type->byref = 1; 
-               ptr++;
-               /* follow through */
-       default:
-               /*if (*ptr == MONO_TYPE_VOID && mode != MONO_PARSE_RET)
-                       g_error ("void not allowed in param");*/
-               do_mono_metadata_parse_type (type, m, ptr, &ptr);
-               break;
-       }
        if (rptr)
                *rptr = ptr;
 
@@ -1288,7 +1309,7 @@ mono_metadata_parse_signature (MonoImage *image, guint32 token)
        guint32 sig;
        const char *ptr;
 
-       if (image->assembly->dynamic)
+       if (image->dynamic)
                return mono_lookup_dynamic_token (image, token);
 
        g_assert (mono_metadata_token_table(token) == MONO_TABLE_STANDALONESIG);
@@ -1309,10 +1330,20 @@ mono_metadata_signature_alloc (MonoImage *m, guint32 nparams)
        /* 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;
+       sig->sentinelpos = -1;
 
        return sig;
 }
 
+MonoMethodSignature*
+mono_metadata_signature_dup (MonoMethodSignature *sig)
+{
+       int sigsize;
+
+       sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
+       return g_memdup (sig, sigsize);
+}
+
 /*
  * mono_metadata_parse_method_signature:
  * @m: metadata context
@@ -1384,6 +1415,10 @@ mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, co
                        method->params [i] = mono_metadata_parse_type (m, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
                }
        }
+
+       if (def && (method->call_convention == MONO_CALL_VARARG))
+               method->sentinelpos = method->param_count;
+
        g_free (pattrs);
 
        if (rptr)
@@ -1411,23 +1446,82 @@ mono_metadata_free_method_signature (MonoMethodSignature *sig)
        g_free (sig);
 }
 
-static MonoGenericInst *
-mono_metadata_parse_generic_inst (MonoImage *m, const char *ptr, const char **rptr)
+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);
+       MonoGenericInst *ginst = g_new0 (MonoGenericInst, 1);
+       MonoType *cached;
        int i, count;
-       
-       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);
 
-       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);
-       
+       type->data.generic_inst = ginst;
+
+       ginst->context = g_new0 (MonoGenericContext, 1);
+       ginst->context->ginst = ginst;
+
+       ginst->klass = g_new0 (MonoClass, 1);
+
+       ginst->generic_type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       ginst->type_argc = count = mono_metadata_decode_value (ptr, &ptr);
+       ginst->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.
+        */
+
+       ginst->init_pending = TRUE;
+
+       mono_class_create_generic (ginst);
+
+       for (i = 0; i < ginst->type_argc; i++) {
+               MonoType *t = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+
+               ginst->type_argv [i] = t;
+               if (!ginst->is_open)
+                       ginst->is_open = mono_class_is_open_constructed_type (t);
+       }
+
+
        if (rptr)
                *rptr = ptr;
 
-       return generic_inst;
+       /*
+        * We may be called multiple times on different metadata to create the same
+        * instantiated type.  This happens for instance if we're part of a method or
+        * local variable signature.
+        *
+        * It's important to return the same MonoGenericInst * for each particualar
+        * instantiation of a generic type (ie "Stack<Int32>") to make static fields
+        * work.
+        *
+        * According to the spec ($26.1.5), a static variable in a generic class
+        * declaration is shared amongst all instances of the same closed constructed
+        * type.
+        */
+
+       cached = g_hash_table_lookup (m->generic_inst_cache, ginst);
+       if (cached) {
+               g_free (ginst->klass);
+               g_free (ginst->type_argv);
+               g_free (ginst);
+
+               type->data.generic_inst = cached->data.generic_inst;
+               return;
+       } else {
+               cached = g_new0 (MonoType, 1);
+               cached->type = MONO_TYPE_GENERICINST;
+               cached->data.generic_inst = ginst;
+
+               g_hash_table_insert (m->generic_inst_cache, ginst, cached);
+
+               mono_stats.generic_instance_count++;
+               mono_stats.generics_metadata_size += sizeof (MonoGenericInst) +
+                       sizeof (MonoGenericContext) +
+                       ginst->type_argc * sizeof (MonoType);
+       }
+
+       ginst->init_pending = FALSE;
 }
 
 static MonoGenericParam *
@@ -1492,6 +1586,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, const char *ptr, cons
        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);
+               mono_metadata_free_type (etype);
                break;
        }
        case MONO_TYPE_PTR:
@@ -1510,7 +1605,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, const char *ptr, cons
                break;
 
        case MONO_TYPE_GENERICINST:
-               type->data.generic_inst = mono_metadata_parse_generic_inst (m, ptr, &ptr);
+               do_mono_metadata_parse_generic_inst (type, m, ptr, &ptr);
                break;
                
        default:
@@ -1851,8 +1946,6 @@ typedef struct {
        guint32 result;
 } locator_t;
 
-#define CSIZE(x) (sizeof (x) / 4)
-
 /*
  * How the row locator works.
  *
@@ -2275,7 +2368,8 @@ mono_type_size (MonoType *t, gint *align)
        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);
+               MonoGenericInst *ginst = t->data.generic_inst;
+               MonoClass *iclass = mono_class_from_mono_type (ginst->generic_type);
                return mono_type_size (&iclass->byval_arg, align);
        }
        case MONO_TYPE_VAR:
@@ -2332,7 +2426,7 @@ mono_type_stack_size (MonoType *t, gint *align)
                return sizeof (gpointer);
        case MONO_TYPE_TYPEDBYREF:
                *align = __alignof__(gpointer);
-               return sizeof (gpointer) * 2;
+               return sizeof (gpointer) * 3;
        case MONO_TYPE_R4:
                *align = __alignof__(float);
                return sizeof (float);          
@@ -2361,7 +2455,8 @@ mono_type_stack_size (MonoType *t, gint *align)
                }
        }
        case MONO_TYPE_GENERICINST: {
-               MonoClass *iclass = mono_class_from_mono_type (t);
+               MonoGenericInst *ginst = t->data.generic_inst;
+               MonoClass *iclass = mono_class_from_mono_type (ginst->generic_type);
                return mono_type_stack_size (&iclass->byval_arg, align);
        }
        default:
@@ -2370,6 +2465,28 @@ mono_type_stack_size (MonoType *t, gint *align)
        return 0;
 }
 
+guint
+mono_metadata_generic_inst_hash (MonoGenericInst *ginst)
+{
+       return mono_metadata_type_hash (ginst->generic_type);
+}
+
+gboolean
+mono_metadata_generic_inst_equal (MonoGenericInst *g1, MonoGenericInst *g2)
+{
+       int i;
+
+       if (g1->type_argc != g2->type_argc)
+               return FALSE;
+       if (!mono_metadata_type_equal (g1->generic_type, g2->generic_type))
+               return FALSE;
+       for (i = 0; i < g1->type_argc; ++i) {
+               if (!mono_metadata_type_equal (g1->type_argv [i], g2->type_argv [i]))
+                       return FALSE;
+       }
+       return TRUE;
+}
+
 /*
  * mono_metadata_type_hash:
  * @t1: a type
@@ -2393,11 +2510,25 @@ mono_metadata_type_hash (MonoType *t1)
        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 << 5) - hash) ^ mono_metadata_generic_inst_hash (t1->data.generic_inst);
        }
        return hash;
 }
 
+static gboolean
+mono_metadata_class_equal (MonoClass *c1, MonoClass *c2)
+{
+       if (c1 == c2)
+               return TRUE;
+       if (c1->generic_inst && c2->generic_inst)
+               return mono_metadata_generic_inst_equal (c1->generic_inst, c2->generic_inst);
+       if ((c1->byval_arg.type == MONO_TYPE_VAR) && (c2->byval_arg.type == MONO_TYPE_VAR))
+               return c1->byval_arg.data.generic_param->num == c2->byval_arg.data.generic_param->num;
+       if ((c1->byval_arg.type == MONO_TYPE_MVAR) && (c2->byval_arg.type == MONO_TYPE_MVAR))
+               return c1->byval_arg.data.generic_param->num == c2->byval_arg.data.generic_param->num;
+       return FALSE;
+}
+
 /*
  * mono_metadata_type_equal:
  * @t1: a type
@@ -2436,28 +2567,19 @@ mono_metadata_type_equal (MonoType *t1, MonoType *t2)
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS:
        case MONO_TYPE_SZARRAY:
-               return t1->data.klass == t2->data.klass;
+               return mono_metadata_class_equal (t1->data.klass, t2->data.klass);
        case MONO_TYPE_PTR:
                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 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;
-       }
+               return mono_metadata_class_equal (t1->data.array->eklass, t2->data.array->eklass);
+       case MONO_TYPE_GENERICINST:
+               return mono_metadata_generic_inst_equal (t1->data.generic_inst,
+                                                        t2->data.generic_inst);
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
-               return t1->data.generic_param == t2->data.generic_param;
+               return t1->data.generic_param->num == t2->data.generic_param->num;
        default:
                g_error ("implement type compare for %0x!", t1->type);
                return FALSE;
@@ -2488,9 +2610,9 @@ 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;
        }
@@ -2526,9 +2648,9 @@ mono_metadata_encode_value (guint32 value, char *buf, char **endbuf)
 {
        char *p = buf;
        
-       if (value <= 127)
+       if (value < 0x80)
                *p++ = value;
-       else if (value <= 16384) {
+       else if (value < 0x4000) {
                p [0] = 0x80 | (value >> 8);
                p [1] = value & 0xff;
                p += 2;
@@ -2608,29 +2730,30 @@ mono_metadata_field_info (MonoImage *meta, guint32 index, guint32 *offset, guint
  * mono_metadata_get_constant_index:
  * @meta: the Image the field is defined in
  * @index: the token that may have a row defined in the constants table
+ * @hint: possible position for the row
  *
  * @token must be a FieldDef, ParamDef or PropertyDef token.
  *
- * Returns: the index into the Constsnts table or 0 if not found.
+ * Returns: the index into the Constants table or 0 if not found.
  */
 guint32
-mono_metadata_get_constant_index (MonoImage *meta, guint32 token)
+mono_metadata_get_constant_index (MonoImage *meta, guint32 token, guint32 hint)
 {
        MonoTableInfo *tdef;
        locator_t loc;
        guint32 index = mono_metadata_token_index (token);
 
        tdef = &meta->tables [MONO_TABLE_CONSTANT];
-       index <<= HASCONSTANT_BITS;
+       index <<= MONO_HASCONSTANT_BITS;
        switch (mono_metadata_token_table (token)) {
        case MONO_TABLE_FIELD:
-               index |= HASCONSTANT_FIEDDEF;
+               index |= MONO_HASCONSTANT_FIEDDEF;
                break;
        case MONO_TABLE_PARAM:
-               index |= HASCONSTANT_PARAM;
+               index |= MONO_HASCONSTANT_PARAM;
                break;
        case MONO_TABLE_PROPERTY:
-               index |= HASCONSTANT_PROPERTY;
+               index |= MONO_HASCONSTANT_PROPERTY;
                break;
        default:
                g_warning ("Not a valid token for the constant table: 0x%08x", token);
@@ -2640,6 +2763,9 @@ mono_metadata_get_constant_index (MonoImage *meta, guint32 token)
        loc.col_idx = MONO_CONSTANT_PARENT;
        loc.t = tdef;
 
+       if ((hint > 0) && (hint < tdef->rows) && (mono_metadata_decode_row_col (tdef, hint - 1, MONO_CONSTANT_PARENT) == index))
+               return hint;
+
        if (tdef->base && bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator)) {
                return loc.result + 1;
        }
@@ -2708,7 +2834,7 @@ mono_metadata_methods_from_event   (MonoImage *meta, guint32 index, guint *end_i
 
        loc.t = msemt;
        loc.col_idx = MONO_METHOD_SEMA_ASSOCIATION;
-       loc.idx = ((index + 1) << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT; /* Method association coded index */
+       loc.idx = ((index + 1) << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT; /* Method association coded index */
 
        if (!bsearch (&loc, msemt->base, msemt->rows, msemt->row_size, table_locator))
                return 0;
@@ -2796,7 +2922,7 @@ mono_metadata_methods_from_property   (MonoImage *meta, guint32 index, guint *en
 
        loc.t = msemt;
        loc.col_idx = MONO_METHOD_SEMA_ASSOCIATION;
-       loc.idx = ((index + 1) << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY; /* Method association coded index */
+       loc.idx = ((index + 1) << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY; /* Method association coded index */
 
        if (!bsearch (&loc, msemt->base, msemt->rows, msemt->row_size, table_locator))
                return 0;
@@ -2833,7 +2959,7 @@ mono_metadata_implmap_from_method (MonoImage *meta, guint32 method_idx)
 
        loc.t = tdef;
        loc.col_idx = MONO_IMPLMAP_MEMBER;
-       loc.idx = ((method_idx + 1) << MEMBERFORWD_BITS) | MEMBERFORWD_METHODDEF;
+       loc.idx = ((method_idx + 1) << MONO_MEMBERFORWD_BITS) | MONO_MEMBERFORWD_METHODDEF;
 
        if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
                return 0;
@@ -2858,12 +2984,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;
 }
@@ -3044,6 +3189,16 @@ handle_enum:
                        case MONO_NATIVE_IUNKNOWN:
                                *conv = MONO_MARSHAL_CONV_OBJECT_IUNKNOWN;
                                return MONO_NATIVE_IUNKNOWN;
+                       case MONO_NATIVE_FUNC:
+                               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;
+                               }
+                               else
+                                       /* Fall through */
+                                       ;
                        default:
                                g_error ("cant marshal object as native type %02x", mspec->native);
                        }
@@ -3076,7 +3231,7 @@ mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field)
 
        loc.t = tdef;
        loc.col_idx = MONO_FIELD_MARSHAL_PARENT;
-       loc.idx = ((idx + 1) << HAS_FIELD_MARSHAL_BITS) | (is_field? HAS_FIELD_MARSHAL_FIELDSREF: HAS_FIELD_MARSHAL_PARAMDEF);
+       loc.idx = ((idx + 1) << MONO_HAS_FIELD_MARSHAL_BITS) | (is_field? MONO_HAS_FIELD_MARSHAL_FIELDSREF: MONO_HAS_FIELD_MARSHAL_PARAMDEF);
 
        if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
                return NULL;
@@ -3087,11 +3242,11 @@ mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field)
 static MonoMethod*
 method_from_method_def_or_ref (MonoImage *m, guint32 tok)
 {
-       guint32 idx = tok >> METHODDEFORREF_BITS;
-       switch (tok & METHODDEFORREF_MASK) {
-       case METHODDEFORREF_METHODDEF:
+       guint32 idx = tok >> MONO_METHODDEFORREF_BITS;
+       switch (tok & MONO_METHODDEFORREF_MASK) {
+       case MONO_METHODDEFORREF_METHODDEF:
                return mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
-       case METHODDEFORREF_METHODREF:
+       case MONO_METHODDEFORREF_METHODREF:
                return mono_get_method (m, MONO_TOKEN_MEMBER_REF | idx, NULL);
        }
        g_assert_not_reached ();
@@ -3202,7 +3357,7 @@ get_constraints (MonoImage *image, int owner)
 }
 
 MonoGenericParam *
-mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num, MonoMethod *method)
+mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num)
 {
        MonoTableInfo *tdef  = &image->tables [MONO_TABLE_GENERICPARAM];
        guint32 cols [MONO_GENERICPARAM_SIZE];
@@ -3231,11 +3386,12 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num
        if (i >= tdef->rows)
                return NULL;
        params = NULL;
-       n = 1;
+       n = 0;
        do {
+               n++;
                params = g_realloc (params, sizeof (MonoGenericParam) * n);
                params [n - 1].pklass = NULL;
-               params [n - 1].method = method;
+               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]);
@@ -3243,7 +3399,6 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num
                if (++i >= tdef->rows)
                        break;
                mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
-               n++;
        } while (cols [MONO_GENERICPARAM_OWNER] == owner);
        
        if (num)
@@ -3251,3 +3406,104 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num
        return params;
 }
 
+gboolean
+mono_type_is_byref (MonoType *type)
+{
+       return type->byref;
+}
+
+int
+mono_type_get_type (MonoType *type)
+{
+       return type->type;
+}
+
+/* For MONO_TYPE_FNPTR */
+MonoMethodSignature*
+mono_type_get_signature (MonoType *type)
+{
+       return type->data.method;
+}
+
+/* For MONO_TYPE_CLASS, VALUETYPE */
+MonoClass*
+mono_type_get_class (MonoType *type)
+{
+       return type->data.klass;
+}
+
+/* For MONO_TYPE_ARRAY */
+MonoArrayType*
+mono_type_get_array_type (MonoType *type)
+{
+       return type->data.array;
+}
+
+MonoClass*
+mono_type_get_modifiers (MonoType *type, gboolean *is_required, gpointer *iter)
+{
+       /* FIXME: implement */
+       return NULL;
+}
+
+MonoType*
+mono_signature_get_return_type (MonoMethodSignature *sig)
+{
+       return sig->ret;
+}
+
+MonoType*
+mono_signature_get_params (MonoMethodSignature *sig, gpointer *iter)
+{
+       MonoType** type;
+       if (!iter)
+               return NULL;
+       if (!*iter) {
+               /* start from the first */
+               if (sig->param_count) {
+                       *iter = &sig->params [0];
+                       return sig->params [0];
+               } else {
+                       /* no method */
+                       return NULL;
+               }
+       }
+       type = *iter;
+       type++;
+       if (type < &sig->params [sig->param_count]) {
+               *iter = type;
+               return *type;
+       }
+       return NULL;
+}
+
+guint32
+mono_signature_get_param_count (MonoMethodSignature *sig)
+{
+       return sig->param_count;
+}
+
+guint32
+mono_signature_get_call_conv (MonoMethodSignature *sig)
+{
+       return sig->call_convention;
+}
+
+int
+mono_signature_vararg_start (MonoMethodSignature *sig)
+{
+       return sig->sentinelpos;
+}
+
+gboolean
+mono_signature_is_instance (MonoMethodSignature *sig)
+{
+       return sig->hasthis;
+}
+
+gboolean
+mono_signature_explicit_this (MonoMethodSignature *sig)
+{
+       return sig->explicit_this;
+}
+