This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mono / metadata / metadata.c
index f8b883b6b27d7fb1d8ad63ff10d9f3a21f136432..3d44463cde90be1fab9068944735fdeb6b6dd1ab 100644 (file)
@@ -1203,6 +1203,10 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
 {
        MonoType *type, *cached;
        gboolean byref = FALSE;
+       gboolean pinned = FALSE;
+       const char *tmp_ptr;
+       int count = 0;
+       gboolean found;
 
        /*
         * According to the spec, custom modifiers should come before the byref
@@ -1212,70 +1216,70 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
         * 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).
         */
-       if (*ptr == MONO_TYPE_BYREF) {
-               byref = TRUE;
-               ++ptr;
-       }
 
-       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++;
+       /* 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;
+               }
+       }
+
+       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");
        }
-       case MONO_PARSE_TYPE:
+       else
                /*
                 * Later we can avoid doing this allocation.
                 */
                type = g_new0 (MonoType, 1);
-               break;
-       default:
-               g_assert_not_reached ();
+
+       /* 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;
-       if (mode == MONO_PARSE_LOCAL) {
-               /*
-                * check for pinned flag
-                */
-               if (*ptr == MONO_TYPE_PINNED) {
-                       type->pinned = 1;
-                       ++ptr;
-               }
-       }
+       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;
 
@@ -2606,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;
        }
@@ -2740,16 +2744,16 @@ mono_metadata_get_constant_index (MonoImage *meta, guint32 token, guint32 hint)
        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);
@@ -2830,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;
@@ -2918,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;
@@ -2955,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;
@@ -3227,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;
@@ -3238,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 ();