[threading] Use a RT signal for abort when possible.
[mono.git] / mono / metadata / metadata.c
index c548a120980f15ba5af1fae0f4f2b9cfcd4bdf5a..138cb114b002d6625d832cc4e30c017104c84f67 100644 (file)
@@ -1761,6 +1761,8 @@ mono_metadata_get_param_attrs (MonoImage *m, int def, int param_count)
 MonoMethodSignature*
 mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *generic_container, guint32 token)
 {
+       MonoError error;
+       MonoMethodSignature *ret;
        MonoTableInfo *tables = image->tables;
        guint32 idx = mono_metadata_token_index (token);
        guint32 sig;
@@ -1776,7 +1778,12 @@ mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *gene
        ptr = mono_metadata_blob_heap (image, sig);
        mono_metadata_decode_blob_size (ptr, &ptr);
 
-       return mono_metadata_parse_method_signature_full (image, generic_container, 0, ptr, NULL); 
+       ret = mono_metadata_parse_method_signature_full (image, generic_container, 0, ptr, NULL, &error);
+       if (!ret) {
+               mono_loader_set_error_from_mono_error (&error);
+               mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
+       }
+       return ret;
 }
 
 /*
@@ -1893,7 +1900,7 @@ mono_metadata_signature_size (MonoMethodSignature *sig)
  */
 MonoMethodSignature *
 mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *container,
-                                          int def, const char *ptr, const char **rptr)
+                                          int def, const char *ptr, const char **rptr, MonoError *error)
 {
        MonoMethodSignature *method;
        int i, *pattrs = NULL;
@@ -1901,6 +1908,8 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
        guint32 gen_param_count = 0;
        gboolean is_open = FALSE;
 
+       mono_error_init (error);
+
        if (*ptr & 0x10)
                gen_param_count = 1;
        if (*ptr & 0x20)
@@ -1927,6 +1936,10 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
                if (!method->ret) {
                        mono_metadata_free_method_signature (method);
                        g_free (pattrs);
+                       if (mono_loader_get_last_error ())
+                               mono_error_set_from_loader_error (error);
+                       else
+                               mono_error_set_bad_image (error, m, "Could not parse return type signature");
                        return NULL;
                }
                is_open = mono_class_is_open_constructed_type (method->ret);
@@ -1935,12 +1948,14 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
        for (i = 0; i < method->param_count; ++i) {
                if (*ptr == MONO_TYPE_SENTINEL) {
                        if (method->call_convention != MONO_CALL_VARARG || def) {
-                               g_warning ("found sentinel for methoddef or no vararg method 0x%08x on image %s", def, m->name);
+                               g_assert (!mono_loader_get_last_error ());
+                               mono_error_set_bad_image (error, m, "Found sentinel for methoddef or no vararg");
                                g_free (pattrs);
                                return NULL;
                        }
                        if (method->sentinelpos >= 0) {
-                               g_warning ("found sentinel twice in the same signature for method 0x%08x on image %s", def, m->name);
+                               g_assert (!mono_loader_get_last_error ());
+                               mono_error_set_bad_image (error, m, "Found sentinel twice in the same signature.");
                                g_free (pattrs);
                                return NULL;
                        }
@@ -1949,6 +1964,10 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
                }
                method->params [i] = mono_metadata_parse_type_full (m, container, MONO_PARSE_PARAM, pattrs ? pattrs [i+1] : 0, ptr, &ptr);
                if (!method->params [i]) {
+                       if (mono_loader_get_last_error ())
+                               mono_error_set_from_loader_error (error);
+                       else
+                               mono_error_set_bad_image (error, m, "Could not parse type argument %d on method signature", i);
                        mono_metadata_free_method_signature (method);
                        g_free (pattrs);
                        return NULL;
@@ -1974,6 +1993,7 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
         * Add signature to a cache and increase ref count...
         */
 
+       g_assert (!mono_loader_get_last_error ());
        return method;
 }
 
@@ -1994,7 +2014,14 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
 MonoMethodSignature *
 mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, const char **rptr)
 {
-       return mono_metadata_parse_method_signature_full (m, NULL, def, ptr, rptr);
+       MonoError error;
+       MonoMethodSignature *ret;
+       ret = mono_metadata_parse_method_signature_full (m, NULL, def, ptr, rptr, &error);
+       if (!ret) {
+               mono_loader_set_error_from_mono_error (&error);
+               mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
+       }
+       return ret;
 }
 
 /*
@@ -3119,6 +3146,8 @@ mono_metadata_get_shared_type (MonoType *type)
                if (type == &type->data.klass->this_arg)
                        return type;
                break;
+       default:
+               break;
        }
 
        return NULL;
@@ -3136,9 +3165,32 @@ compare_type_literals (int class_type, int type_type)
        /* NET 1.1 assemblies might encode string and object in a denormalized way.
         * See #675464.
         */
-       if (type_type == MONO_TYPE_CLASS && (class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT))
+       if (class_type == type_type)
+               return TRUE;
+
+       if (type_type == MONO_TYPE_CLASS)
+               return class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT;
+
+       g_assert (type_type == MONO_TYPE_VALUETYPE);
+       switch (class_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_I8:
+       case MONO_TYPE_U8:
+       case MONO_TYPE_R4:
+       case MONO_TYPE_R8:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U:
                return TRUE;
-       return class_type == type_type;
+       default:
+               return FALSE;
+       }
 }
 
 /* 
@@ -3220,11 +3272,16 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer
                if (!type->data.type)
                        return FALSE;
                break;
-       case MONO_TYPE_FNPTR:
-               type->data.method = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr);
-               if (!type->data.method)
+       case MONO_TYPE_FNPTR: {
+               MonoError error;
+               type->data.method = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr, &error);
+               if (!type->data.method) {
+                       mono_loader_set_error_from_mono_error (&error);
+                       mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
                        return FALSE;
+               }
                break;
+       }
        case MONO_TYPE_ARRAY:
                type->data.array = mono_metadata_parse_array_internal (m, container, transient, ptr, &ptr);
                if (!type->data.array)
@@ -3283,6 +3340,8 @@ mono_metadata_free_type (MonoType *type)
        case MONO_TYPE_ARRAY:
                mono_metadata_free_array (type->data.array);
                break;
+       default:
+               break;
        }
 
        g_free (type);
@@ -3318,14 +3377,13 @@ static MonoExceptionClause*
 parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr)
 {
        unsigned char sect_data_flags;
-       const unsigned char *sptr;
        int is_fat;
        guint32 sect_data_len;
        MonoExceptionClause* clauses = NULL;
        
        while (1) {
                /* align on 32-bit boundary */
-               sptr = ptr = dword_align (ptr); 
+               ptr = dword_align (ptr); 
                sect_data_flags = *ptr;
                ptr++;
                
@@ -3337,14 +3395,7 @@ parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr)
                        sect_data_len = ptr [0];
                        ++ptr;
                }
-               /*
-               g_print ("flags: %02x, len: %d\n", sect_data_flags, sect_data_len);
-               hex_dump (sptr, 0, sect_data_len+8);
-               g_print ("\nheader: ");
-               hex_dump (sptr-4, 0, 4);
-               g_print ("\n");
-               */
-               
+
                if (sect_data_flags & METHOD_HEADER_SECTION_EHTABLE) {
                        const unsigned char *p = dword_align (ptr);
                        int i;
@@ -3493,7 +3544,7 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
        guint32 local_var_sig_tok, max_stack, code_size, init_locals;
        const unsigned char *code;
        MonoExceptionClause* clauses = NULL;
-       int hsize, num_clauses = 0;
+       int num_clauses = 0;
        MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
        guint32 cols [MONO_STAND_ALONE_SIGNATURE_SIZE];
 
@@ -3512,7 +3563,6 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
        case METHOD_HEADER_FAT_FORMAT:
                fat_flags = read16 (ptr);
                ptr += 2;
-               hsize = (fat_flags >> 12) & 0xf;
                max_stack = read16 (ptr);
                ptr += 2;
                code_size = read32 (ptr);
@@ -3552,10 +3602,10 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
                clauses = parse_section_data (m, &num_clauses, (const unsigned char*)ptr);
        if (local_var_sig_tok) {
                const char *locals_ptr;
-               int len=0, i, bsize;
+               int len=0, i;
 
                locals_ptr = mono_metadata_blob_heap (m, cols [MONO_STAND_ALONE_SIGNATURE]);
-               bsize = mono_metadata_decode_blob_size (locals_ptr, &locals_ptr);
+               mono_metadata_decode_blob_size (locals_ptr, &locals_ptr);
                if (*locals_ptr != 0x07)
                        g_warning ("wrong signature for locals blob");
                locals_ptr++;
@@ -4004,7 +4054,7 @@ mono_metadata_typedef_from_method (MonoImage *meta, guint32 index)
  * Returns: TRUE on success, FALSE on failure.
  */
 gboolean
-mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, gboolean heap_alloc_result, MonoGenericContext *context)
+mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, gboolean heap_alloc_result, MonoGenericContext *context, MonoError *error)
 {
        MonoTableInfo *tdef = &meta->tables [MONO_TABLE_INTERFACEIMPL];
        locator_t loc;
@@ -4015,6 +4065,8 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
        *interfaces = NULL;
        *count = 0;
 
+       mono_error_init (error);
+
        if (!tdef->base)
                return TRUE;
 
@@ -4050,19 +4102,15 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
 
        pos = start;
        while (pos < tdef->rows) {
-               MonoError error;
                MonoClass *iface;
                
                mono_metadata_decode_row (tdef, pos, cols, MONO_INTERFACEIMPL_SIZE);
                if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx)
                        break;
                iface = mono_class_get_and_inflate_typespec_checked (
-                       meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context, &error);
-               if (iface == NULL) {
-                       mono_loader_set_error_from_mono_error (&error);
-                       mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+                       meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context, error);
+               if (iface == NULL)
                        return FALSE;
-               }
                result [pos - start] = iface;
                ++pos;
        }
@@ -4088,10 +4136,12 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
 MonoClass**
 mono_metadata_interfaces_from_typedef (MonoImage *meta, guint32 index, guint *count)
 {
-       MonoClass **interfaces;
+       MonoError error;
+       MonoClass **interfaces = NULL;
        gboolean rv;
 
-       rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, TRUE, NULL);
+       rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, TRUE, NULL, &error);
+       g_assert (mono_error_ok (&error)); /* FIXME dont swallow the error */
        if (rv)
                return interfaces;
        else
@@ -4313,6 +4363,8 @@ mono_type_set_alignment (MonoTypeEnum type, int align)
 int
 mono_type_size (MonoType *t, int *align)
 {
+       MonoTypeEnum simple_type;
+
        if (!t) {
                *align = 1;
                return 0;
@@ -4322,7 +4374,9 @@ mono_type_size (MonoType *t, int *align)
                return sizeof (gpointer);
        }
 
-       switch (t->type){
+       simple_type = t->type;
+ again:
+       switch (simple_type) {
        case MONO_TYPE_VOID:
                *align = 1;
                return 0;
@@ -4395,9 +4449,14 @@ mono_type_size (MonoType *t, int *align)
        }
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
-               /* FIXME: Martin, this is wrong. */
-               *align = MONO_ABI_ALIGNOF (gpointer);
-               return sizeof (gpointer);
+               if (t->data.generic_param->gshared_constraint == 0 || t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE) {
+                       *align = MONO_ABI_ALIGNOF (gpointer);
+                       return sizeof (gpointer);
+               } else {
+                       /* The gparam can only match types given by gshared_constraint */
+                       simple_type = t->data.generic_param->gshared_constraint;
+                       goto again;
+               }
        default:
                g_error ("mono_type_size: type 0x%02x unknown", t->type);
        }
@@ -4421,6 +4480,7 @@ int
 mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
 {
        int tmp;
+       MonoTypeEnum simple_type;
 #if SIZEOF_VOID_P == SIZEOF_REGISTER
        int stack_slot_size = sizeof (gpointer);
        int stack_slot_align = MONO_ABI_ALIGNOF (gpointer);
@@ -4439,7 +4499,9 @@ mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
                return stack_slot_size;
        }
 
-       switch (t->type){
+       simple_type = t->type;
+ again:
+       switch (simple_type) {
        case MONO_TYPE_BOOLEAN:
        case MONO_TYPE_CHAR:
        case MONO_TYPE_I1:
@@ -4462,8 +4524,14 @@ mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                g_assert (allow_open);
-               *align = stack_slot_align;
-               return stack_slot_size;
+               if (t->data.generic_param->gshared_constraint == 0 || t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE) {
+                       *align = stack_slot_align;
+                       return stack_slot_size;
+               } else {
+                       /* The gparam can only match types given by gshared_constraint */
+                       simple_type = t->data.generic_param->gshared_constraint;
+                       goto again;
+               }
        case MONO_TYPE_TYPEDBYREF:
                *align = stack_slot_align;
                return stack_slot_size * 3;
@@ -4646,8 +4714,9 @@ mono_metadata_type_hash (MonoType *t1)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                return ((hash << 5) - hash) ^ mono_metadata_generic_param_hash (t1->data.generic_param);
+       default:
+               return hash;
        }
-       return hash;
 }
 
 static guint
@@ -4656,7 +4725,7 @@ mono_metadata_generic_param_hash (MonoGenericParam *p)
        guint hash;
        MonoGenericParamInfo *info;
 
-       hash = (mono_generic_param_num (p) << 2) | p->serial;
+       hash = (mono_generic_param_num (p) << 2) | p->gshared_constraint;
        info = mono_generic_param_info (p);
        /* Can't hash on the owner klass/method, since those might not be set when this is called */
        if (info)
@@ -4671,7 +4740,7 @@ mono_metadata_generic_param_equal (MonoGenericParam *p1, MonoGenericParam *p2, g
                return TRUE;
        if (mono_generic_param_num (p1) != mono_generic_param_num (p2))
                return FALSE;
-       if (p1->serial != p2->serial)
+       if (p1->gshared_constraint != p2->gshared_constraint)
                return FALSE;
 
        /*
@@ -5301,10 +5370,8 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec)
 {
        MonoError error;
        MonoType *type = mono_type_create_from_typespec_checked (image, type_spec, &error);
-       if (!type) {
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error); /* FIXME don't swallow error*/
-       }
+       if (!type)
+                g_error ("Could not create typespec %x due to %s", type_spec, mono_error_get_message (&error));
        return type;
 }
 
@@ -5316,7 +5383,6 @@ mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, Mon
        MonoTableInfo *t;
        guint32 cols [MONO_TYPESPEC_SIZE];
        const char *ptr;
-       guint32 len;
        MonoType *type, *type2;
 
        mono_error_init (error);
@@ -5337,7 +5403,7 @@ mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, Mon
                return NULL;
        }
 
-       len = mono_metadata_decode_value (ptr, &ptr);
+       mono_metadata_decode_value (ptr, &ptr);
 
        type = mono_metadata_parse_type_internal (image, NULL, MONO_PARSE_TYPE, 0, TRUE, ptr, &ptr);
        if (!type) {
@@ -5694,18 +5760,25 @@ mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field)
 }
 
 MonoMethod*
-method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context)
+method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context, MonoError *error)
 {
+       MonoMethod *result = NULL;
        guint32 idx = tok >> MONO_METHODDEFORREF_BITS;
 
+       mono_error_init (error);
+
        switch (tok & MONO_METHODDEFORREF_MASK) {
        case MONO_METHODDEFORREF_METHODDEF:
-               return mono_get_method_full (m, MONO_TOKEN_METHOD_DEF | idx, NULL, context);
+               result = mono_get_method_checked (m, MONO_TOKEN_METHOD_DEF | idx, NULL, context, error);
+               break;
        case MONO_METHODDEFORREF_METHODREF:
-               return mono_get_method_full (m, MONO_TOKEN_MEMBER_REF | idx, NULL, context);
+               result = mono_get_method_checked (m, MONO_TOKEN_MEMBER_REF | idx, NULL, context, error);
+               break;
+       default:
+               mono_error_set_bad_image (error, m, "Invalid MethodDefOfRef token %x", tok);
        }
-       g_assert_not_reached ();
-       return NULL;
+
+       return result;
 }
 
 /*
@@ -5766,21 +5839,25 @@ mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod
                MonoMethod *method;
 
                if (!mono_verifier_verify_methodimpl_row (image, start + i, &error)) {
-                       mono_error_cleanup (&error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        ok = FALSE;
                        break;
                }
 
                mono_metadata_decode_row (tdef, start + i, cols, MONO_METHODIMPL_SIZE);
                method = method_from_method_def_or_ref (
-                       image, cols [MONO_METHODIMPL_DECLARATION], generic_context);
-               if (method == NULL)
+                       image, cols [MONO_METHODIMPL_DECLARATION], generic_context, &error);
+               if (method == NULL) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        ok = FALSE;
+               }
                result [i * 2] = method;
                method = method_from_method_def_or_ref (
-                       image, cols [MONO_METHODIMPL_BODY], generic_context);
-               if (method == NULL)
+                       image, cols [MONO_METHODIMPL_BODY], generic_context, &error);
+               if (method == NULL) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        ok = FALSE;
+               }
                result [i * 2 + 1] = method;
        }