First set of licensing changes
[mono.git] / mono / metadata / loader.c
index b99d6a00b1168fc4ccd5be41af8686ab7c62bb64..f9b83480b52262a3647136ce9aeb5ebf96025386 100644 (file)
@@ -17,6 +17,7 @@
  * TODO:
  *   This should keep track of the assembly versions that we are loading.
  *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
 #include <glib.h>
@@ -56,7 +57,8 @@ MonoDefaults mono_defaults;
  * See domain-internals.h for locking policy in combination with the
  * domain lock.
  */
-static mono_mutex_t loader_mutex, global_loader_data_mutex;
+static MonoCoopMutex loader_mutex;
+static mono_mutex_t global_loader_data_mutex;
 static gboolean loader_lock_inited;
 
 /* Statistics */
@@ -82,13 +84,13 @@ static void dllmap_cleanup (void);
 static void
 global_loader_data_lock (void)
 {
-       mono_locks_acquire (&global_loader_data_mutex, LoaderGlobalDataLock);
+       mono_locks_os_acquire (&global_loader_data_mutex, LoaderGlobalDataLock);
 }
 
 static void
 global_loader_data_unlock (void)
 {
-       mono_locks_release (&global_loader_data_mutex, LoaderGlobalDataLock);
+       mono_locks_os_release (&global_loader_data_mutex, LoaderGlobalDataLock);
 }
 
 void
@@ -97,8 +99,8 @@ mono_loader_init ()
        static gboolean inited;
 
        if (!inited) {
-               mono_mutex_init_recursive (&loader_mutex);
-               mono_mutex_init_recursive (&global_loader_data_mutex);
+               mono_coop_mutex_init_recursive (&loader_mutex);
+               mono_os_mutex_init_recursive (&global_loader_data_mutex);
                loader_lock_inited = TRUE;
 
                mono_native_tls_alloc (&loader_error_thread_id, NULL);
@@ -126,8 +128,8 @@ mono_loader_cleanup (void)
        mono_native_tls_free (loader_error_thread_id);
        mono_native_tls_free (loader_lock_nest_id);
 
-       mono_mutex_destroy (&loader_mutex);
-       mono_mutex_destroy (&global_loader_data_mutex);
+       mono_coop_mutex_destroy (&loader_mutex);
+       mono_os_mutex_destroy (&global_loader_data_mutex);
        loader_lock_inited = FALSE;     
 }
 
@@ -460,7 +462,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
        MonoTableInfo *tables = image->tables;
        MonoType *sig_type;
        guint32 cols[6];
-       guint32 nindex, class;
+       guint32 nindex, class_index;
        const char *fname;
        const char *ptr;
        guint32 idx = mono_metadata_token_index (token);
@@ -469,16 +471,16 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
 
        mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE);
        nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS;
-       class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
+       class_index = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
 
        fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
 
        if (!mono_verifier_verify_memberref_field_signature (image, cols [MONO_MEMBERREF_SIGNATURE], NULL)) {
-               mono_error_set_bad_image (error, image, "Bad field '%s' signature 0x%08x", class, token);
+               mono_error_set_bad_image (error, image, "Bad field '%s' signature 0x%08x", class_index, token);
                return NULL;
        }
 
-       switch (class) {
+       switch (class_index) {
        case MONO_MEMBERREF_PARENT_TYPEDEF:
                klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | nindex, error);
                break;
@@ -489,7 +491,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
                klass = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_SPEC | nindex, context, error);
                break;
        default:
-               mono_error_set_bad_image (error, image, "Bad field field '%s' signature 0x%08x", class, token);
+               mono_error_set_bad_image (error, image, "Bad field field '%s' signature 0x%08x", class_index, token);
        }
 
        if (!klass)
@@ -500,21 +502,25 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
        /* we may want to check the signature here... */
 
        if (*ptr++ != 0x6) {
-               mono_error_set_field_load (error, klass, fname, "Bad field signature class token %08x field name %s token %08x", class, fname, token);
+               mono_error_set_field_load (error, klass, fname, "Bad field signature class token %08x field name %s token %08x", class_index, fname, token);
                return NULL;
        }
 
        /* FIXME: This needs a cache, especially for generic instances, since
-        * mono_metadata_parse_type () allocates everything from a mempool.
+        * we ask mono_metadata_parse_type_checked () to allocates everything from a mempool.
+        * FIXME part2, mono_metadata_parse_type_checked actually allows for a transient type instead.
+        * FIXME part3, transient types are not 100% transient, so we need to take care of that first.
         */
-       sig_type = find_cached_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE]);
+       sig_type = (MonoType *)find_cached_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE]);
        if (!sig_type) {
-               sig_type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+               MonoError inner_error;
+               sig_type = mono_metadata_parse_type_checked (image, NULL, 0, FALSE, ptr, &ptr, &inner_error);
                if (sig_type == NULL) {
-                       mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x", fname, token);
+                       mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x due to: %s", fname, token, mono_error_get_message (&inner_error));
+                       mono_error_cleanup (&inner_error);
                        return NULL;
                }
-               sig_type = cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type);
+               sig_type = (MonoType *)cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type);
        }
 
        mono_class_init (klass); /*FIXME is this really necessary?*/
@@ -533,17 +539,14 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
 /*
  * mono_field_from_token:
  * @deprecated use the _checked variant
+ * Notes: runtime code MUST not use this function
 */
 MonoClassField*
 mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, MonoGenericContext *context)
 {
        MonoError error;
        MonoClassField *res = mono_field_from_token_checked (image, token, retklass, context, &error);
-       mono_loader_assert_no_error ();
-       if (!mono_error_ok (&error)) {
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error);
-       }
+       g_assert (mono_error_ok (&error));
        return res;
 }
 
@@ -561,7 +564,7 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk
                MonoClass *handle_class;
 
                *retklass = NULL;
-               result = mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
+               result = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
                // This checks the memberref type as well
                if (!result || handle_class != mono_defaults.fieldhandle_class) {
                        mono_error_set_bad_image (error, image, "Bad field token 0x%08x", token);
@@ -571,7 +574,7 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk
                return result;
        }
 
-       if ((field = mono_conc_hashtable_lookup (image->field_cache, GUINT_TO_POINTER (token)))) {
+       if ((field = (MonoClassField *)mono_conc_hashtable_lookup (image->field_cache, GUINT_TO_POINTER (token)))) {
                *retklass = field->parent;
                return field;
        }
@@ -681,7 +684,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
        See mono/tests/generic-type-load-exception.2.il
        FIXME we should better report this error to the caller
         */
-       if (!klass->methods || klass->exception_type) {
+       if (!klass->methods || mono_class_has_failure (klass)) {
                mono_error_set_type_load_class (error, klass, "Could not find method due to a type load error"); //FIXME get the error from the class 
 
                return NULL;
@@ -814,7 +817,7 @@ inflate_generic_signature_checked (MonoImage *image, MonoMethodSignature *sig, M
        if (!context)
                return sig;
 
-       res = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + ((gint32)sig->param_count) * sizeof (MonoType*));
+       res = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + ((gint32)sig->param_count) * sizeof (MonoType*));
        res->param_count = sig->param_count;
        res->sentinelpos = -1;
        res->ret = mono_class_inflate_generic_type_checked (sig->ret, context, error);
@@ -870,11 +873,11 @@ mono_inflate_generic_signature (MonoMethodSignature *sig, MonoGenericContext *co
 }
 
 static MonoMethodHeader*
-inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
+inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context, MonoError *error)
 {
        MonoMethodHeader *res;
        int i;
-       res = g_malloc0 (MONO_SIZEOF_METHOD_HEADER + sizeof (gpointer) * header->num_locals);
+       res = (MonoMethodHeader *)g_malloc0 (MONO_SIZEOF_METHOD_HEADER + sizeof (gpointer) * header->num_locals);
        res->code = header->code;
        res->code_size = header->code_size;
        res->max_stack = header->max_stack;
@@ -882,36 +885,42 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
        res->init_locals = header->init_locals;
        res->num_locals = header->num_locals;
        res->clauses = header->clauses;
-       for (i = 0; i < header->num_locals; ++i)
-               res->locals [i] = mono_class_inflate_generic_type (header->locals [i], context);
+
+       mono_error_init (error);
+
+       for (i = 0; i < header->num_locals; ++i) {
+               res->locals [i] = mono_class_inflate_generic_type_checked (header->locals [i], context, error);
+               if (!is_ok (error))
+                       goto fail;
+       }
        if (res->num_clauses) {
-               res->clauses = g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses);
+               res->clauses = (MonoExceptionClause *)g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses);
                for (i = 0; i < header->num_clauses; ++i) {
                        MonoExceptionClause *clause = &res->clauses [i];
                        if (clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
                                continue;
-                       clause->data.catch_class = mono_class_inflate_generic_class (clause->data.catch_class, context);
+                       clause->data.catch_class = mono_class_inflate_generic_class_checked (clause->data.catch_class, context, error);
+                       if (!is_ok (error))
+                               goto fail;
                }
        }
        return res;
+fail:
+       g_free (res);
+       return NULL;
 }
 
 /*
  * token is the method_ref/def/spec token used in a call IL instruction.
+ * @deprecated use the _checked variant
+ * Notes: runtime code MUST not use this function
  */
 MonoMethodSignature*
 mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context)
 {
        MonoError error;
        MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, context, &error);
-
-       mono_loader_assert_no_error ();
-
-       if (!res) {
-               g_assert (!mono_error_ok (&error));
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error); /* FIXME Don't swallow the error */
-       }
+       mono_error_cleanup (&error);
        return res;
 }
 
@@ -933,8 +942,10 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32
 
        if (table == MONO_TABLE_METHODSPEC) {
                /* the verifier (do_invoke_method) will turn the NULL into a verifier error */
-               if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated)
+               if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated) {
+                       mono_error_set_bad_image (error, image, "Method is a pinvoke or open generic");
                        return NULL;
+               }
 
                return mono_method_signature_checked (method, error);
        }
@@ -950,14 +961,14 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32
                mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE);
                sig_idx = cols [MONO_MEMBERREF_SIGNATURE];
 
-               sig = find_cached_memberref_sig (image, sig_idx);
+               sig = (MonoMethodSignature *)find_cached_memberref_sig (image, sig_idx);
                if (!sig) {
                        if (!mono_verifier_verify_memberref_method_signature (image, sig_idx, NULL)) {
-                               guint32 class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
+                               guint32 klass = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
                                const char *fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
 
                                //FIXME include the verification error
-                               mono_error_set_bad_image (error, image, "Bad method signature class token 0x%08x field name %s token 0x%08x", class, fname, token);
+                               mono_error_set_bad_image (error, image, "Bad method signature class token 0x%08x field name %s token 0x%08x", klass, fname, token);
                                return NULL;
                        }
 
@@ -968,14 +979,14 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32
                        if (!sig)
                                return NULL;
 
-                       sig = cache_memberref_sig (image, sig_idx, sig);
+                       sig = (MonoMethodSignature *)cache_memberref_sig (image, sig_idx, sig);
                }
                /* FIXME: we probably should verify signature compat in the dynamic case too*/
                if (!mono_verifier_is_sig_compatible (image, method, sig)) {
-                       guint32 class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
+                       guint32 klass = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
                        const char *fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
 
-                       mono_error_set_bad_image (error, image, "Incompatible method signature class token 0x%08x field name %s token 0x%08x", class, fname, token);
+                       mono_error_set_bad_image (error, image, "Incompatible method signature class token 0x%08x field name %s token 0x%08x", klass, fname, token);
                        return NULL;
                }
        }
@@ -1000,19 +1011,17 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32
        return sig;
 }
 
+/*
+ * token is the method_ref/def/spec token used in a call IL instruction.
+ * @deprecated use the _checked variant
+ * Notes: runtime code MUST not use this function
+ */
 MonoMethodSignature*
 mono_method_get_signature (MonoMethod *method, MonoImage *image, guint32 token)
 {
        MonoError error;
        MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, NULL, &error);
-
-       mono_loader_assert_no_error ();
-
-       if (!res) {
-               g_assert (!mono_error_ok (&error));
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error); /* FIXME Don't swallow the error */
-       }
+       mono_error_cleanup (&error);
        return res;
 }
 
@@ -1023,7 +1032,7 @@ mono_method_search_in_array_class (MonoClass *klass, const char *name, MonoMetho
        int i;
 
        mono_class_setup_methods (klass);
-       g_assert (!klass->exception_type); /*FIXME this should not fail, right?*/
+       g_assert (!mono_class_has_failure (klass)); /*FIXME this should not fail, right?*/
        for (i = 0; i < klass->method.count; ++i) {
                MonoMethod *method = klass->methods [i];
                if (strcmp (method->name, name) == 0 && sig->param_count == method->signature->param_count)
@@ -1040,7 +1049,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
        MonoMethod *method = NULL;
        MonoTableInfo *tables = image->tables;
        guint32 cols[6];
-       guint32 nindex, class, sig_idx;
+       guint32 nindex, class_index, sig_idx;
        const char *mname;
        MonoMethodSignature *sig;
        const char *ptr;
@@ -1049,7 +1058,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
 
        mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, 3);
        nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS;
-       class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
+       class_index = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
        /*g_print ("methodref: 0x%x 0x%x %s\n", class, nindex,
                mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]));*/
 
@@ -1061,9 +1070,9 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
         * method into a cache.
         */
        if (used_context)
-               *used_context = class == MONO_MEMBERREF_PARENT_TYPESPEC;
+               *used_context = class_index == MONO_MEMBERREF_PARENT_TYPESPEC;
 
-       switch (class) {
+       switch (class_index) {
        case MONO_MEMBERREF_PARENT_TYPEREF:
                klass = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | nindex, error);
                if (!klass)
@@ -1089,7 +1098,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
                return method;
        }
        default:
-               mono_error_set_bad_image (error, image, "Memberref parent unknown: class: %d, index %d", class, nindex);
+               mono_error_set_bad_image (error, image, "Memberref parent unknown: class: %d, index %d", class_index, nindex);
                goto fail;
        }
 
@@ -1106,16 +1115,16 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
        ptr = mono_metadata_blob_heap (image, sig_idx);
        mono_metadata_decode_blob_size (ptr, &ptr);
 
-       sig = find_cached_memberref_sig (image, sig_idx);
+       sig = (MonoMethodSignature *)find_cached_memberref_sig (image, sig_idx);
        if (!sig) {
                sig = mono_metadata_parse_method_signature_full (image, NULL, 0, ptr, NULL, error);
                if (sig == NULL)
                        goto fail;
 
-               sig = cache_memberref_sig (image, sig_idx, sig);
+               sig = (MonoMethodSignature *)cache_memberref_sig (image, sig_idx, sig);
        }
 
-       switch (class) {
+       switch (class_index) {
        case MONO_MEMBERREF_PARENT_TYPEREF:
        case MONO_MEMBERREF_PARENT_TYPEDEF:
                method = find_method (klass, NULL, mname, sig, klass, error);
@@ -1137,7 +1146,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
                break;
        }
        default:
-               mono_error_set_bad_image (error, image,"Memberref parent unknown: class: %d, index %d", class, nindex);
+               mono_error_set_bad_image (error, image,"Memberref parent unknown: class: %d, index %d", class_index, nindex);
                goto fail;
        }
 
@@ -1331,7 +1340,7 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons
        mono_loader_init ();
 
        if (!assembly) {
-               entry = g_malloc0 (sizeof (MonoDllMap));
+               entry = (MonoDllMap *)g_malloc0 (sizeof (MonoDllMap));
                entry->dll = dll? g_strdup (dll): NULL;
                entry->target = tdll? g_strdup (tdll): NULL;
                entry->func = func? g_strdup (func): NULL;
@@ -1342,7 +1351,7 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons
                global_dll_map = entry;
                global_loader_data_unlock ();
        } else {
-               entry = mono_image_alloc0 (assembly, sizeof (MonoDllMap));
+               entry = (MonoDllMap *)mono_image_alloc0 (assembly, sizeof (MonoDllMap));
                entry->dll = dll? mono_image_strdup (assembly, dll): NULL;
                entry->target = tdll? mono_image_strdup (assembly, tdll): NULL;
                entry->func = func? mono_image_strdup (assembly, func): NULL;
@@ -1389,7 +1398,7 @@ cached_module_load (const char *name, int flags, char **err)
        global_loader_data_lock ();
        if (!global_module_map)
                global_module_map = g_hash_table_new (g_str_hash, g_str_equal);
-       res = g_hash_table_lookup (global_module_map, name);
+       res = (MonoDl *)g_hash_table_lookup (global_module_map, name);
        if (res) {
                global_loader_data_unlock ();
                return res;
@@ -1445,7 +1454,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
 
        if (image_is_dynamic (method->klass->image)) {
                MonoReflectionMethodAux *method_aux = 
-                       g_hash_table_lookup (
+                       (MonoReflectionMethodAux *)g_hash_table_lookup (
                                ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
                if (!method_aux)
                        return NULL;
@@ -1476,8 +1485,8 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
                        image->pinvoke_scopes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
                        image->pinvoke_scope_filenames = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
                }
-               module = g_hash_table_lookup (image->pinvoke_scopes, new_scope);
-               found_name = g_hash_table_lookup (image->pinvoke_scope_filenames, new_scope);
+               module = (MonoDl *)g_hash_table_lookup (image->pinvoke_scopes, new_scope);
+               found_name = (char *)g_hash_table_lookup (image->pinvoke_scope_filenames, new_scope);
                mono_image_unlock (image);
                if (module)
                        cached = TRUE;
@@ -1865,7 +1874,7 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
        if (image_is_dynamic (image)) {
                MonoClass *handle_class;
 
-               result = mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
+               result = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
                mono_loader_assert_no_error ();
 
                // This checks the memberref type as well
@@ -1942,6 +1951,7 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
        if (generic_container) {
                result->is_generic = TRUE;
                generic_container->owner.method = result;
+               generic_container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
                /*FIXME put this before the image alloc*/
                if (!mono_metadata_load_generic_param_constraints_checked (image, token, generic_container, error))
                        return NULL;
@@ -1978,7 +1988,10 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
 MonoMethod *
 mono_get_method (MonoImage *image, guint32 token, MonoClass *klass)
 {
-       return mono_get_method_full (image, token, klass, NULL);
+       MonoError error;
+       MonoMethod *result = mono_get_method_checked (image, token, klass, NULL, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
 
 MonoMethod *
@@ -1987,11 +2000,7 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass,
 {
        MonoError error;
        MonoMethod *result = mono_get_method_checked (image, token, klass, context, &error);
-       mono_loader_assert_no_error ();
-       if (!mono_error_ok (&error)) {
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error);
-       }
+       mono_error_cleanup (&error);
        return result;
 }
 
@@ -2010,11 +2019,11 @@ mono_get_method_checked (MonoImage *image, guint32 token, MonoClass *klass, Mono
        if (mono_metadata_token_table (token) == MONO_TABLE_METHOD) {
                if (!image->method_cache)
                        image->method_cache = g_hash_table_new (NULL, NULL);
-               result = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)));
+               result = (MonoMethod *)g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)));
        } else if (!image_is_dynamic (image)) {
                if (!image->methodref_cache)
                        image->methodref_cache = g_hash_table_new (NULL, NULL);
-               result = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token));
+               result = (MonoMethod *)g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token));
        }
        mono_image_unlock (image);
 
@@ -2031,9 +2040,9 @@ mono_get_method_checked (MonoImage *image, guint32 token, MonoClass *klass, Mono
                MonoMethod *result2 = NULL;
 
                if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
-                       result2 = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)));
+                       result2 = (MonoMethod *)g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)));
                else if (!image_is_dynamic (image))
-                       result2 = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token));
+                       result2 = (MonoMethod *)g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token));
 
                if (result2) {
                        mono_image_unlock (image);
@@ -2134,12 +2143,7 @@ mono_get_method_constrained (MonoImage *image, guint32 token, MonoClass *constra
 {
        MonoError error;
        MonoMethod *result = mono_get_method_constrained_checked (image, token, constrained_class, context, cil_method, &error);
-
-       mono_loader_assert_no_error ();
-       if (!mono_error_ok (&error)) {
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error);
-       }
+       mono_error_cleanup (&error);
        return result;
 }
 
@@ -2229,7 +2233,7 @@ mono_method_get_param_names (MonoMethod *method, const char **names)
 
        if (image_is_dynamic (klass->image)) {
                MonoReflectionMethodAux *method_aux = 
-                       g_hash_table_lookup (
+                       (MonoReflectionMethodAux *)g_hash_table_lookup (
                                ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
                if (method_aux && method_aux->param_names) {
                        for (i = 0; i < mono_method_signature (method)->param_count; ++i)
@@ -2244,7 +2248,7 @@ mono_method_get_param_names (MonoMethod *method, const char **names)
 
                mono_image_lock (klass->image);
                if (klass->image->wrapper_param_names)
-                       pnames = g_hash_table_lookup (klass->image->wrapper_param_names, method);
+                       pnames = (char **)g_hash_table_lookup (klass->image->wrapper_param_names, method);
                mono_image_unlock (klass->image);
 
                if (pnames) {
@@ -2320,7 +2324,7 @@ mono_method_get_marshal_info (MonoMethod *method, MonoMarshalSpec **mspecs)
 
        if (image_is_dynamic (method->klass->image)) {
                MonoReflectionMethodAux *method_aux = 
-                       g_hash_table_lookup (
+                       (MonoReflectionMethodAux *)g_hash_table_lookup (
                                ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
                if (method_aux && method_aux->param_marshall) {
                        MonoMarshalSpec **dyn_specs = method_aux->param_marshall;
@@ -2375,7 +2379,7 @@ mono_method_has_marshal_info (MonoMethod *method)
 
        if (image_is_dynamic (method->klass->image)) {
                MonoReflectionMethodAux *method_aux = 
-                       g_hash_table_lookup (
+                       (MonoReflectionMethodAux *)g_hash_table_lookup (
                                ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
                MonoMarshalSpec **dyn_specs = method_aux->param_marshall;
                if (dyn_specs) {
@@ -2420,7 +2424,7 @@ mono_method_get_wrapper_data (MonoMethod *method, guint32 id)
 
        if (method->is_inflated)
                method = ((MonoMethodInflated *) method)->declaring;
-       data = ((MonoMethodWrapper *)method)->method_data;
+       data = (void **)((MonoMethodWrapper *)method)->method_data;
        g_assert (data != NULL);
        g_assert (id <= GPOINTER_TO_UINT (*data));
        return data [id];
@@ -2434,7 +2438,7 @@ typedef struct {
 static gboolean
 stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
 {
-       StackWalkUserData *d = data;
+       StackWalkUserData *d = (StackWalkUserData *)data;
 
        switch (frame->type) {
        case FRAME_TYPE_DEBUGGER_INVOKE:
@@ -2474,7 +2478,7 @@ typedef struct {
 static gboolean
 async_stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
 {
-       AsyncStackWalkUserData *d = data;
+       AsyncStackWalkUserData *d = (AsyncStackWalkUserData *)data;
 
        switch (frame->type) {
        case FRAME_TYPE_DEBUGGER_INVOKE:
@@ -2515,7 +2519,7 @@ mono_stack_walk_async_safe (MonoStackWalkAsyncSafe func, void *initial_sig_conte
 static gboolean
 last_managed (MonoMethod *m, gint no, gint ilo, gboolean managed, gpointer data)
 {
-       MonoMethod **dest = data;
+       MonoMethod **dest = (MonoMethod **)data;
        *dest = m;
        /*g_print ("In %s::%s [%d] [%d]\n", m->klass->name, m->name, no, ilo);*/
 
@@ -2540,10 +2544,7 @@ static gboolean loader_lock_track_ownership = FALSE;
 void
 mono_loader_lock (void)
 {
-       MONO_TRY_BLOCKING;
-       mono_locks_acquire (&loader_mutex, LoaderLock);
-       MONO_FINISH_TRY_BLOCKING;
-               
+       mono_locks_coop_acquire (&loader_mutex, LoaderLock);
        if (G_UNLIKELY (loader_lock_track_ownership)) {
                mono_native_tls_set_value (loader_lock_nest_id, GUINT_TO_POINTER (GPOINTER_TO_UINT (mono_native_tls_get_value (loader_lock_nest_id)) + 1));
        }
@@ -2552,7 +2553,7 @@ mono_loader_lock (void)
 void
 mono_loader_unlock (void)
 {
-       mono_locks_release (&loader_mutex, LoaderLock);
+       mono_locks_coop_release (&loader_mutex, LoaderLock);
        if (G_UNLIKELY (loader_lock_track_ownership)) {
                mono_native_tls_set_value (loader_lock_nest_id, GUINT_TO_POINTER (GPOINTER_TO_UINT (mono_native_tls_get_value (loader_lock_nest_id)) - 1));
        }
@@ -2671,7 +2672,7 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error)
 
        if (can_cache_signature) {
                mono_image_lock (img);
-               signature = g_hash_table_lookup (img->method_signatures, sig);
+               signature = (MonoMethodSignature *)g_hash_table_lookup (img->method_signatures, sig);
                mono_image_unlock (img);
        }
 
@@ -2689,7 +2690,7 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error)
 
                if (can_cache_signature) {
                        mono_image_lock (img);
-                       sig2 = g_hash_table_lookup (img->method_signatures, sig);
+                       sig2 = (MonoMethodSignature *)g_hash_table_lookup (img->method_signatures, sig);
                        if (!sig2)
                                g_hash_table_insert (img->method_signatures, (gpointer)sig, signature);
                        mono_image_unlock (img);
@@ -2715,7 +2716,7 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error)
        if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
                signature->pinvoke = 1;
        else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
-               MonoCallConvention conv = 0;
+               MonoCallConvention conv = (MonoCallConvention)0;
                MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)m;
                signature->pinvoke = 1;
 
@@ -2797,30 +2798,35 @@ mono_method_get_token (MonoMethod *method)
 }
 
 MonoMethodHeader*
-mono_method_get_header (MonoMethod *method)
+mono_method_get_header_checked (MonoMethod *method, MonoError *error)
 {
        int idx;
        guint32 rva;
        MonoImage* img;
        gpointer loc;
-       MonoMethodHeader *header;
        MonoGenericContainer *container;
 
-       if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
-               return NULL;
-
+       mono_error_init (error);
        img = method->klass->image;
 
+       if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
+               mono_error_set_bad_image (error, img, "Method has no body");
+               return NULL;
+       }
+
        if (method->is_inflated) {
                MonoMethodInflated *imethod = (MonoMethodInflated *) method;
                MonoMethodHeader *header, *iheader;
 
-               header = mono_method_get_header (imethod->declaring);
+               header = mono_method_get_header_checked (imethod->declaring, error);
                if (!header)
                        return NULL;
 
-               iheader = inflate_generic_header (header, mono_method_get_context (method));
+               iheader = inflate_generic_header (header, mono_method_get_context (method), error);
                mono_metadata_free_mh (header);
+               if (!iheader) {
+                       return NULL;
+               }
 
                mono_image_lock (img);
 
@@ -2852,12 +2858,16 @@ mono_method_get_header (MonoMethod *method)
        idx = mono_metadata_token_index (method->token);
        rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA);
 
-       if (!mono_verifier_verify_method_header (img, rva, NULL))
+       if (!mono_verifier_verify_method_header (img, rva, NULL)) {
+               mono_error_set_bad_image (error, img, "Invalid method header, failed verification");
                return NULL;
+       }
 
        loc = mono_image_rva_map (img, rva);
-       if (!loc)
+       if (!loc) {
+               mono_error_set_bad_image (error, img, "Method has zero rva");
                return NULL;
+       }
 
        /*
         * When parsing the types of local variables, we must pass any container available
@@ -2866,11 +2876,19 @@ mono_method_get_header (MonoMethod *method)
        container = mono_method_get_generic_container (method);
        if (!container)
                container = method->klass->generic_container;
-       header = mono_metadata_parse_mh_full (img, container, loc);
+       return mono_metadata_parse_mh_full (img, container, (const char *)loc, error);
+}
 
+MonoMethodHeader*
+mono_method_get_header (MonoMethod *method)
+{
+       MonoError error;
+       MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
+       mono_error_cleanup (&error);
        return header;
 }
 
+
 guint32
 mono_method_get_flags (MonoMethod *method, guint32 *iflags)
 {
@@ -2896,7 +2914,7 @@ mono_method_get_index (MonoMethod *method)
                return mono_metadata_token_index (method->token);
 
        mono_class_setup_methods (klass);
-       if (klass->exception_type)
+       if (mono_class_has_failure (klass))
                return 0;
        for (i = 0; i < klass->method.count; ++i) {
                if (method == klass->methods [i]) {