First set of licensing changes
[mono.git] / mono / metadata / class.c
index b6538c7d6f1b0af3d9a6de886ad853ad8c75f3a3..9422028afd6a3709e0d6a0f8005b0d0c5504b191 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  * Copyright 2012 Xamarin Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
 #ifdef HAVE_ALLOCA_H
@@ -631,11 +632,11 @@ mono_type_get_underlying_type (MonoType *type)
        return type;
 }
 
-/*
+/**
  * mono_class_is_open_constructed_type:
  * @type: a type
  *
- * Returns TRUE if type represents a generics open constructed type.
+ * Returns: TRUE if type represents a generics open constructed type.
  * IOW, not all type parameters required for the instantiation have
  * been provided or it's a generic type definition.
  *
@@ -905,11 +906,7 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context)
        MonoError error;
        MonoType *result;
        result = mono_class_inflate_generic_type_checked (type, context, &error);
-
-       if (!mono_error_ok (&error)) {
-               mono_error_cleanup (&error);
-               return NULL;
-       }
+       mono_error_cleanup (&error);
        return result;
 }
 
@@ -955,6 +952,11 @@ mono_class_inflate_generic_type_no_copy (MonoImage *image, MonoType *type, MonoG
        return inflated;
 }
 
+/*
+ * mono_class_inflate_generic_class:
+ *
+ *   Inflate the class @gklass with @context. Set @error on failure.
+ */
 MonoClass*
 mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext *context, MonoError *error)
 {
@@ -969,24 +971,6 @@ mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext
 
        return res;
 }
-/*
- * mono_class_inflate_generic_class:
- *
- *   Inflate the class GKLASS with CONTEXT.
- */
-MonoClass*
-mono_class_inflate_generic_class (MonoClass *gklass, MonoGenericContext *context)
-{
-       MonoError error;
-       MonoClass *res;
-
-       res = mono_class_inflate_generic_class_checked (gklass, context, &error);
-       g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
-
-       return res;
-}
-
-
 
 static MonoGenericContext
 inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflate_with, MonoError *error)
@@ -1350,14 +1334,10 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error)
                        goto fail;
                }
 
-               ftype = mono_metadata_parse_type_full (m, container, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
-               if (!ftype) {
-                       if (mono_loader_get_last_error ()) /*FIXME plug the above to not leak errors*/
-                               mono_error_set_from_loader_error (error);
-                       else
-                               mono_error_set_bad_image (error, klass->image, "Could not parse type for field signature %x", cols [MONO_FIELD_SIGNATURE]);
+               ftype = mono_metadata_parse_type_checked (m, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
+               if (!ftype)
                        goto fail;
-               }
+
                if (klass->generic_class) {
                        //FIXME do we leak here?
                        ftype = mono_class_inflate_generic_type_checked (ftype, mono_class_get_context (klass), error);
@@ -1385,11 +1365,11 @@ mono_type_has_exceptions (MonoType *type)
        case MONO_TYPE_CLASS:
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_SZARRAY:
-               return type->data.klass->exception_type;
+               return mono_class_has_failure (type->data.klass);
        case MONO_TYPE_ARRAY:
-               return type->data.array->eklass->exception_type;
+               return mono_class_has_failure (type->data.array->eklass);
        case MONO_TYPE_GENERICINST:
-               return mono_generic_class_get_class (type->data.generic_class)->exception_type;
+               return mono_class_has_failure (mono_generic_class_get_class (type->data.generic_class));
        default:
                return FALSE;
        }
@@ -1501,6 +1481,7 @@ mono_class_setup_fields (MonoClass *klass)
        int i, blittable = TRUE;
        guint32 real_size = 0;
        guint32 packing_size = 0;
+       int instance_size;
        gboolean explicit_size;
        MonoClassField *field;
        MonoGenericContainer *container = NULL;
@@ -1570,13 +1551,13 @@ mono_class_setup_fields (MonoClass *klass)
 
        if (gtd) {
                mono_class_setup_fields (gtd);
-               if (gtd->exception_type) {
+               if (mono_class_has_failure (gtd)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                        return;
                }
        }
 
-       klass->instance_size = 0;
+       instance_size = 0;
        if (!klass->rank)
                klass->sizes.class_size = 0;
 
@@ -1585,18 +1566,18 @@ mono_class_setup_fields (MonoClass *klass)
                mono_class_init (klass->parent);
                if (!klass->parent->size_inited) {
                        mono_class_setup_fields (klass->parent);
-                       if (klass->parent->exception_type) {
+                       if (mono_class_has_failure (klass->parent)) {
                                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                                return;
                        }
                }
-               klass->instance_size += klass->parent->instance_size;
+               instance_size += klass->parent->instance_size;
                klass->min_align = klass->parent->min_align;
                /* we use |= since it may have been set already */
                klass->has_references |= klass->parent->has_references;
                blittable = klass->parent->blittable;
        } else {
-               klass->instance_size = sizeof (MonoObject);
+               instance_size = sizeof (MonoObject);
                klass->min_align = 1;
        }
 
@@ -1618,14 +1599,16 @@ mono_class_setup_fields (MonoClass *klass)
                        return;
                }
                klass->packing_size = packing_size;
-               real_size += klass->instance_size;
+               real_size += instance_size;
        }
 
        if (!top) {
                if (explicit_size && real_size) {
-                       klass->instance_size = MAX (real_size, klass->instance_size);
+                       instance_size = MAX (real_size, instance_size);
                }
                klass->blittable = blittable;
+               if (!klass->instance_size)
+                       klass->instance_size = instance_size;
                mono_memory_barrier ();
                klass->size_inited = 1;
                klass->fields_inited = 1;
@@ -1701,7 +1684,7 @@ mono_class_setup_fields (MonoClass *klass)
                                MonoClass *field_class = mono_class_from_mono_type (field->type);
                                if (field_class) {
                                        mono_class_setup_fields (field_class);
-                                       if (field_class->exception_type) {
+                                       if (mono_class_has_failure (field_class)) {
                                                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                                                break;
                                        }
@@ -1739,12 +1722,12 @@ mono_class_setup_fields (MonoClass *klass)
                return;
        }
        if (explicit_size && real_size) {
-               klass->instance_size = MAX (real_size, klass->instance_size);
+               instance_size = MAX (real_size, instance_size);
        }
 
-       if (klass->exception_type)
+       if (mono_class_has_failure (klass))
                return;
-       mono_class_layout_fields (klass);
+       mono_class_layout_fields (klass, instance_size);
 
        /*valuetypes can't be neither bigger than 1Mb or empty. */
        if (klass->valuetype && (klass->instance_size <= 0 || klass->instance_size > (0x100000 + sizeof (MonoObject))))
@@ -1825,6 +1808,7 @@ type_has_references (MonoClass *klass, MonoType *ftype)
 /*
  * mono_class_layout_fields:
  * @class: a class
+ * @instance_size: base instance size
  *
  * Compute the placement of fields inside an object or struct, according to
  * the layout rules and set the following fields in @class:
@@ -1837,7 +1821,7 @@ type_has_references (MonoClass *klass, MonoType *ftype)
  * LOCKING: this is supposed to be called with the loader lock held.
  */
 void
-mono_class_layout_fields (MonoClass *klass)
+mono_class_layout_fields (MonoClass *klass, int instance_size)
 {
        int i;
        const int top = klass->field.count;
@@ -1918,7 +1902,6 @@ mono_class_layout_fields (MonoClass *klass)
        /*
         * Compute field layout and total size (not considering static fields)
         */
-
        switch (layout) {
        case TYPE_ATTRIBUTE_AUTO_LAYOUT:
        case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT:
@@ -1933,7 +1916,7 @@ mono_class_layout_fields (MonoClass *klass)
 
                if (klass->parent) {
                        mono_class_setup_fields (klass->parent);
-                       if (klass->parent->exception_type) {
+                       if (mono_class_has_failure (klass->parent)) {
                                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                                return;
                        }
@@ -1994,11 +1977,11 @@ mono_class_layout_fields (MonoClass *klass)
                                real_size = field->offset + size;
                        }
 
-                       klass->instance_size = MAX (real_size, klass->instance_size);
+                       instance_size = MAX (real_size, instance_size);
        
-                       if (klass->instance_size & (klass->min_align - 1)) {
-                               klass->instance_size += klass->min_align - 1;
-                               klass->instance_size &= ~(klass->min_align - 1);
+                       if (instance_size & (klass->min_align - 1)) {
+                               instance_size += klass->min_align - 1;
+                               instance_size &= ~(klass->min_align - 1);
                        }
                }
                break;
@@ -2083,10 +2066,10 @@ mono_class_layout_fields (MonoClass *klass)
                        g_free (ref_bitmap);
                }
 
-               klass->instance_size = MAX (real_size, klass->instance_size);
-               if (klass->instance_size & (klass->min_align - 1)) {
-                       klass->instance_size += klass->min_align - 1;
-                       klass->instance_size &= ~(klass->min_align - 1);
+               instance_size = MAX (real_size, instance_size);
+               if (instance_size & (klass->min_align - 1)) {
+                       instance_size += klass->min_align - 1;
+                       instance_size &= ~(klass->min_align - 1);
                }
                break;
        }
@@ -2102,11 +2085,17 @@ mono_class_layout_fields (MonoClass *klass)
                 * unaligned accesses otherwise. See #78990 for a testcase.
                 */
                if (mono_align_small_structs) {
-                       if (klass->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
-                               klass->min_align = MAX (klass->min_align, klass->instance_size - sizeof (MonoObject));
+                       if (instance_size <= sizeof (MonoObject) + sizeof (gpointer))
+                               klass->min_align = MAX (klass->min_align, instance_size - sizeof (MonoObject));
                }
        }
 
+       if (klass->instance_size && !klass->image->dynamic) {
+               /* Might be already set using cached info */
+               g_assert (klass->instance_size == instance_size);
+       } else {
+               klass->instance_size = instance_size;
+       }
        mono_memory_barrier ();
        klass->size_inited = 1;
 
@@ -2191,9 +2180,9 @@ mono_class_setup_methods (MonoClass *klass)
                MonoClass *gklass = klass->generic_class->container_class;
 
                mono_class_init (gklass);
-               if (!gklass->exception_type)
+               if (!mono_class_has_failure (gklass))
                        mono_class_setup_methods (gklass);
-               if (gklass->exception_type) {
+               if (mono_class_has_failure (gklass)) {
                        /* FIXME make exception_data less opaque so it's possible to dup it here */
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
                        return;
@@ -2374,7 +2363,7 @@ mono_class_get_method_by_index (MonoClass *klass, int index)
                return m;
        } else {
                mono_class_setup_methods (klass);
-               if (klass->exception_type) /*FIXME do proper error handling*/
+               if (mono_class_has_failure (klass)) /*FIXME do proper error handling*/
                        return NULL;
                g_assert (index >= 0 && index < klass->method.count);
                return klass->methods [index];
@@ -2396,7 +2385,7 @@ mono_class_get_inflated_method (MonoClass *klass, MonoMethod *method)
        g_assert (method->klass == gklass);
 
        mono_class_setup_methods (gklass);
-       g_assert (!gklass->exception_type); /*FIXME do proper error handling*/
+       g_assert (!mono_class_has_failure (gklass)); /*FIXME do proper error handling*/
 
        for (i = 0; i < gklass->method.count; ++i) {
                if (gklass->methods [i] == method) {
@@ -2445,7 +2434,7 @@ mono_class_get_vtable_entry (MonoClass *klass, int offset)
                g_assert (mono_error_ok (&error)); /* FIXME don't swallow this error */
        } else {
                mono_class_setup_vtable (klass);
-               if (klass->exception_type)
+               if (mono_class_has_failure (klass))
                        return NULL;
                m = klass->vtable [offset];
        }
@@ -2491,7 +2480,7 @@ mono_class_setup_properties (MonoClass *klass)
 
                mono_class_init (gklass);
                mono_class_setup_properties (gklass);
-               if (gklass->exception_type) {
+               if (mono_class_has_failure (gklass)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
                        return;
                }
@@ -2523,7 +2512,7 @@ mono_class_setup_properties (MonoClass *klass)
 
                if (count) {
                        mono_class_setup_methods (klass);
-                       if (klass->exception_type)
+                       if (mono_class_has_failure (klass))
                                return;
                }
 
@@ -2624,7 +2613,7 @@ mono_class_setup_events (MonoClass *klass)
                MonoGenericContext *context = NULL;
 
                mono_class_setup_events (gklass);
-               if (gklass->exception_type) {
+               if (mono_class_has_failure (gklass)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
                        return;
                }
@@ -2664,7 +2653,7 @@ mono_class_setup_events (MonoClass *klass)
 
                if (count) {
                        mono_class_setup_methods (klass);
-                       if (klass->exception_type) {
+                       if (mono_class_has_failure (klass)) {
                                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
                                return;
                        }
@@ -2863,7 +2852,7 @@ collect_implemented_interfaces_aux (MonoClass *klass, GPtrArray **res, MonoError
                        *res = g_ptr_array_new ();
                g_ptr_array_add (*res, ic);
                mono_class_init (ic);
-               if (ic->exception_type) {
+               if (mono_class_has_failure (ic)) {
                        mono_error_set_type_load_class (error, ic, "Error Loading class");
                        return;
                }
@@ -2911,7 +2900,7 @@ mono_class_interface_offset (MonoClass *klass, MonoClass *itf) {
        }
 }
 
-/*
+/**
  * mono_class_interface_offset_with_variance:
  * 
  * Return the interface offset of @itf in @klass. Sets @non_exact_match to TRUE if the match required variance check
@@ -3106,15 +3095,15 @@ get_implicit_generic_array_interfaces (MonoClass *klass, int *num, int *is_enume
        all_interfaces = eclass->rank && eclass->element_class->rank? FALSE: TRUE;
 
        if (!generic_icollection_class) {
-               generic_icollection_class = mono_class_from_name (mono_defaults.corlib,
+               generic_icollection_class = mono_class_load_from_name (mono_defaults.corlib,
                        "System.Collections.Generic", "ICollection`1");
-               generic_ienumerable_class = mono_class_from_name (mono_defaults.corlib,
+               generic_ienumerable_class = mono_class_load_from_name (mono_defaults.corlib,
                        "System.Collections.Generic", "IEnumerable`1");
-               generic_ienumerator_class = mono_class_from_name (mono_defaults.corlib,
+               generic_ienumerator_class = mono_class_load_from_name (mono_defaults.corlib,
                        "System.Collections.Generic", "IEnumerator`1");
-               generic_ireadonlylist_class = mono_class_from_name (mono_defaults.corlib,
+               generic_ireadonlylist_class = mono_class_load_from_name (mono_defaults.corlib,
                        "System.Collections.Generic", "IReadOnlyList`1");
-               generic_ireadonlycollection_class = mono_class_from_name (mono_defaults.corlib,
+               generic_ireadonlycollection_class = mono_class_load_from_name (mono_defaults.corlib,
                        "System.Collections.Generic", "IReadOnlyCollection`1");
        }
 
@@ -3298,7 +3287,7 @@ count_virtual_methods (MonoClass *klass)
 
        if (klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass)) {
                mono_class_setup_methods (klass);
-               if (klass->exception_type)
+               if (mono_class_has_failure (klass))
                        return -1;
 
                for (i = 0; i < klass->method.count; ++i) {
@@ -3766,11 +3755,11 @@ mono_class_check_vtable_constraints (MonoClass *klass, GList *in_setup)
        int i;
        if (!klass->generic_class) {
                mono_class_setup_vtable_full (klass, in_setup);
-               return klass->exception_type == 0;
+               return !mono_class_has_failure (klass);
        }
 
        mono_class_setup_vtable_full (mono_class_get_generic_type_definition (klass), in_setup);
-       if (klass->generic_class->container_class->exception_type) {
+       if (mono_class_has_failure (klass->generic_class->container_class)) {
                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Failed to load generic definition vtable"));
                return FALSE;
        }
@@ -3813,6 +3802,7 @@ mono_class_setup_vtable (MonoClass *klass)
 static void
 mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
 {
+       MonoError error;
        MonoMethod **overrides;
        MonoGenericContext *context;
        guint32 type_token;
@@ -3828,7 +3818,7 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
                return;
        }
 
-       if (klass->exception_type)
+       if (mono_class_has_failure (klass))
                return;
 
        if (g_list_find (in_setup, klass))
@@ -3863,7 +3853,14 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
                 * This is true since we don't do layout all over again for them, we simply inflate
                 * the layout of the parent.
                 */
-               mono_reflection_get_dynamic_overrides (klass, &overrides, &onum);
+               mono_reflection_get_dynamic_overrides (klass, &overrides, &onum, &error);
+               if (!is_ok (&error)) {
+                       mono_loader_unlock ();
+                       g_list_remove (in_setup, klass);
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf("Could not load list of method overrides due to %s", mono_error_get_message (&error)));
+                       mono_error_cleanup (&error);
+                       return;
+               }
        } else {
                /* The following call fails if there are missing methods in the type */
                /* FIXME it's probably a good idea to avoid this for generic instances. */
@@ -4222,7 +4219,7 @@ print_unimplemented_interface_method_info (MonoClass *klass, MonoClass *ic, Mono
        g_free (method_signature);
        g_free (type_name);
        mono_class_setup_methods (klass);
-       if (klass->exception_type) {
+       if (mono_class_has_failure (klass)) {
                char *name = mono_type_get_full_name (klass);
                mono_trace_warning (MONO_TRACE_TYPE, "CLASS %s failed to resolve methods\n", name);
                g_free (name);
@@ -4346,7 +4343,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                mono_class_init (klass->parent);
                mono_class_setup_vtable_full (klass->parent, in_setup);
 
-               if (klass->parent->exception_type) {
+               if (mono_class_has_failure (klass->parent)) {
                        char *name = mono_type_get_full_name (klass->parent);
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Parent %s failed to load", name));
                        g_free (name);
@@ -4385,7 +4382,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                MonoMethod **tmp;
 
                mono_class_setup_vtable_full (gklass, in_setup);
-               if (gklass->exception_type != MONO_EXCEPTION_NONE) {
+               if (mono_class_has_failure (gklass)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                        return;
                }
@@ -4441,7 +4438,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                                
                                mono_class_setup_methods (parent_interface); /*FIXME Just kill this whole chunk of dead code*/
                                TRACE_INTERFACE_VTABLE (printf ("    +++ Inheriting interface %s.%s\n", parent_interface->name_space, parent_interface->name));
-                               for (j = 0; j < parent_interface->method.count && !klass->exception_type; j++) {
+                               for (j = 0; j < parent_interface->method.count && !mono_class_has_failure (klass); j++) {
                                        vtable [interface_offset + j] = parent->vtable [parent_interface_offset + j];
                                        TRACE_INTERFACE_VTABLE (printf ("    --- Inheriting: [%03d][(%03d)+(%03d)] => [%03d][(%03d)+(%03d)]\n",
                                                        parent_interface_offset + j, parent_interface_offset, j,
@@ -4503,7 +4500,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                while ((cm = mono_class_get_virtual_methods (klass, &iter))) {
                        virt_methods = g_slist_prepend (virt_methods, cm);
                }
-               if (klass->exception_type)
+               if (mono_class_has_failure (klass))
                        goto fail;
        }
        
@@ -4518,7 +4515,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                ic_offset = mono_class_interface_offset (klass, ic);
 
                mono_class_setup_methods (ic);
-               if (ic->exception_type)
+               if (mono_class_has_failure (ic))
                        goto fail;
                
                // Check if this interface is explicitly implemented (instead of just inherited)
@@ -4565,7 +4562,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                                                }
                                        }
                                        TRACE_INTERFACE_VTABLE (printf ("\n"));
-                                       if (klass->exception_type)  /*Might be set by check_interface_method_override*/
+                                       if (mono_class_has_failure (klass))  /*Might be set by check_interface_method_override*/
                                                goto fail;
                                }
                                
@@ -4586,7 +4583,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                                                        }
                                                        break;
                                                }
-                                               if (klass->exception_type) /*Might be set by check_interface_method_override*/
+                                               if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/
                                                        goto fail;
                                                TRACE_INTERFACE_VTABLE ((cm != NULL) && printf ("\n"));
                                        }
@@ -4681,7 +4678,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                                                break;
                                        }
                                }
-                               if (k->exception_type)
+                               if (mono_class_has_failure (k))
                                        goto fail;
                                
                                if (slot >= 0) 
@@ -4856,7 +4853,7 @@ mono_method_get_vtable_slot (MonoMethod *method)
 {
        if (method->slot == -1) {
                mono_class_setup_vtable (method->klass);
-               if (method->klass->exception_type)
+               if (mono_class_has_failure (method->klass))
                        return -1;
                if (method->slot == -1) {
                        MonoClass *gklass;
@@ -4952,7 +4949,7 @@ generic_array_methods (MonoClass *klass)
        if (generic_array_method_num)
                return generic_array_method_num;
        mono_class_setup_methods (klass->parent); /*This is setting up System.Array*/
-       g_assert (!klass->parent->exception_type); /*So hitting this assert is a huge problem*/
+       g_assert (!mono_class_has_failure (klass->parent)); /*So hitting this assert is a huge problem*/
        for (i = 0; i < klass->parent->method.count; i++) {
                MonoMethod *m = klass->parent->methods [i];
                if (!strncmp (m->name, "InternalArray__", 15)) {
@@ -5112,18 +5109,18 @@ mono_class_init (MonoClass *klass)
        g_assert (klass);
 
        /* Double-checking locking pattern */
-       if (klass->inited || klass->exception_type)
-               return klass->exception_type == MONO_EXCEPTION_NONE;
+       if (klass->inited || mono_class_has_failure (klass))
+               return !mono_class_has_failure (klass);
 
        /*g_print ("Init class %s\n", mono_type_get_full_name (klass));*/
 
        /* We do everything inside the lock to prevent races */
        mono_loader_lock ();
 
-       if (klass->inited || klass->exception_type) {
+       if (klass->inited || mono_class_has_failure (klass)) {
                mono_loader_unlock ();
                /* Somebody might have gotten in before us */
-               return klass->exception_type == MONO_EXCEPTION_NONE;
+               return !mono_class_has_failure (klass);
        }
 
        if (klass->init_pending) {
@@ -5143,7 +5140,7 @@ mono_class_init (MonoClass *klass)
                MonoClass *element_class = klass->element_class;
                if (!element_class->inited) 
                        mono_class_init (element_class);
-               if (element_class->exception_type != MONO_EXCEPTION_NONE) {
+               if (mono_class_has_failure (element_class)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                        goto leave;
                }
@@ -5161,9 +5158,9 @@ mono_class_init (MonoClass *klass)
 
                mono_class_init (gklass);
                // FIXME: Why is this needed ?
-               if (!gklass->exception_type)
+               if (!mono_class_has_failure (gklass))
                        mono_class_setup_methods (gklass);
-               if (gklass->exception_type) {
+               if (mono_class_has_failure (gklass)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Generic Type Defintion failed to init"));
                        goto leave;
                }
@@ -5196,7 +5193,7 @@ mono_class_init (MonoClass *klass)
        else
                if (!klass->size_inited){
                        mono_class_setup_fields (klass);
-                       if (klass->exception_type || mono_loader_get_last_error ())
+                       if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
                                goto leave;
                }
                                
@@ -5250,7 +5247,7 @@ mono_class_init (MonoClass *klass)
                klass->has_cctor = gklass->has_cctor;
 
                mono_class_setup_vtable (gklass);
-               if (gklass->exception_type) {
+               if (mono_class_has_failure (gklass)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                        goto leave;
                }
@@ -5282,7 +5279,7 @@ mono_class_init (MonoClass *klass)
                                        klass->has_cctor = 1;
                        } else {
                                mono_class_setup_methods (klass);
-                               if (klass->exception_type)
+                               if (mono_class_has_failure (klass))
                                        goto leave;
 
                                for (i = 0; i < klass->method.count; ++i) {
@@ -5301,7 +5298,7 @@ mono_class_init (MonoClass *klass)
                int first_iface_slot;
                /* This will compute klass->parent->vtable_size for some classes */
                mono_class_init (klass->parent);
-               if (klass->parent->exception_type) {
+               if (mono_class_has_failure (klass->parent)) {
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                        goto leave;
                }
@@ -5310,7 +5307,7 @@ mono_class_init (MonoClass *klass)
                if (!klass->parent->vtable_size) {
                        /* FIXME: Get rid of this somehow */
                        mono_class_setup_vtable (klass->parent);
-                       if (klass->parent->exception_type) {
+                       if (mono_class_has_failure (klass->parent)) {
                                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                                goto leave;
                        }
@@ -5329,7 +5326,7 @@ mono_class_init (MonoClass *klass)
                mono_security_core_clr_check_inheritance (klass);
 
        if (mono_loader_get_last_error ()) {
-               if (klass->exception_type == MONO_EXCEPTION_NONE) {
+               if (!mono_class_has_failure (klass)) {
                        set_failure_from_loader_error (klass, mono_loader_get_last_error ());
                }
                mono_loader_clear_error ();
@@ -5348,7 +5345,7 @@ mono_class_init (MonoClass *klass)
 
        mono_loader_unlock ();
 
-       return klass->exception_type == MONO_EXCEPTION_NONE;
+       return !mono_class_has_failure (klass);
 }
 
 /*
@@ -5383,7 +5380,7 @@ mono_class_has_finalizer (MonoClass *klass)
                                 * ignores overrides.
                                 */
                                mono_class_setup_vtable (klass);
-                               if (klass->exception_type || mono_loader_get_last_error ())
+                               if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
                                        cmethod = NULL;
                                else
                                        cmethod = klass->vtable [finalize_slot];
@@ -5738,22 +5735,6 @@ mono_class_set_failure_and_error (MonoClass *klass, MonoError *error, const char
        mono_error_set_type_load_class (error, klass, msg);
 }
 
-static void
-mono_class_set_failure_from_loader_error (MonoClass *klass, MonoError *error, char *msg)
-{
-       MonoLoaderError *lerror = mono_loader_get_last_error ();
-
-       if (lerror) {
-               set_failure_from_loader_error (klass, lerror);
-               mono_error_set_from_loader_error (error);
-               if (msg)
-                       g_free (msg);
-       } else {
-               mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, msg);
-               mono_error_set_type_load_class (error, klass, msg);
-       }
-}
-
 /**
  * mono_class_create_from_typedef:
  * @image: image where the token is valid
@@ -6221,7 +6202,7 @@ make_generic_param_class (MonoGenericParam *param, MonoGenericParamInfo *pinfo)
                CHECKED_METADATA_WRITE_PTR ( klass->parent , pinfo->constraints [0] );
                pos++;
        } else if (pinfo && pinfo->flags & GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT) {
-               CHECKED_METADATA_WRITE_PTR ( klass->parent , mono_class_from_name (mono_defaults.corlib, "System", "ValueType") );
+               CHECKED_METADATA_WRITE_PTR ( klass->parent , mono_class_load_from_name (mono_defaults.corlib, "System", "ValueType") );
        } else {
                CHECKED_METADATA_WRITE_PTR ( klass->parent , mono_defaults.object_class );
        }
@@ -6265,7 +6246,7 @@ make_generic_param_class (MonoGenericParam *param, MonoGenericParamInfo *pinfo)
 
        if (count - pos > 0) {
                mono_class_setup_vtable (klass->parent);
-               if (klass->parent->exception_type)
+               if (mono_class_has_failure (klass->parent))
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Failed to setup parent interfaces"));
                else
                        setup_interface_offsets (klass, klass->parent->vtable_size, TRUE);
@@ -6747,7 +6728,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
 
        /* for the building corlib use System.Array from it */
        if (image->assembly && assembly_is_dynamic (image->assembly) && image->assembly_name && strcmp (image->assembly_name, "mscorlib") == 0) {
-               parent = mono_class_from_name (image, "System", "Array");
+               parent = mono_class_load_from_name (image, "System", "Array");
                corlib_type = TRUE;
        } else {
                parent = mono_defaults.array_class;
@@ -6784,7 +6765,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
 
        if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF || eclass->byval_arg.type == MONO_TYPE_VOID) {
                /*Arrays of those two types are invalid.*/
-               mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+               mono_class_set_failure (klass, MONO_EXCEPTION_INVALID_PROGRAM, NULL);
        } else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) {
                if (!eclass->ref_info_handle || eclass->wastypebuilder) {
                        g_warning ("Only incomplete TypeBuilder objects are allowed to be an enum without base_type");
@@ -6801,7 +6782,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
                mono_class_init (eclass);
        if (!eclass->size_inited)
                mono_class_setup_fields (eclass);
-       if (eclass->exception_type) /*FIXME we fail the array type, but we have to let other fields be set.*/
+       if (mono_class_has_failure (eclass)) /*FIXME we fail the array type, but we have to let other fields be set.*/
                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
 
        klass->has_references = MONO_TYPE_IS_REFERENCE (&eclass->byval_arg) || eclass->has_references? TRUE: FALSE;
@@ -6989,7 +6970,7 @@ static MonoClassField *
 mono_class_get_field_idx (MonoClass *klass, int idx)
 {
        mono_class_setup_fields_locking (klass);
-       if (klass->exception_type)
+       if (mono_class_has_failure (klass))
                return NULL;
 
        while (klass) {
@@ -7071,7 +7052,7 @@ mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoTyp
        int i;
 
        mono_class_setup_fields_locking (klass);
-       if (klass->exception_type)
+       if (mono_class_has_failure (klass))
                return NULL;
 
        while (klass) {
@@ -7737,7 +7718,8 @@ mono_class_from_name_case (MonoImage *image, const char* name_space, const char
 {
        MonoError error;
        MonoClass *res = mono_class_from_name_case_checked (image, name_space, name, &error);
-       g_assert (!mono_error_ok (&error));
+       mono_error_cleanup (&error);
+
        return res;
 }
 
@@ -7840,13 +7822,15 @@ return_nested_in (MonoClass *klass, char *nested)
 }
 
 static MonoClass*
-search_modules (MonoImage *image, const char *name_space, const char *name)
+search_modules (MonoImage *image, const char *name_space, const char *name, MonoError *error)
 {
        MonoTableInfo *file_table = &image->tables [MONO_TABLE_FILE];
        MonoImage *file_image;
        MonoClass *klass;
        int i;
 
+       mono_error_init (error);
+
        /* 
         * The EXPORTEDTYPES table only contains public types, so have to search the
         * modules as well.
@@ -7861,8 +7845,8 @@ search_modules (MonoImage *image, const char *name_space, const char *name)
 
                file_image = mono_image_load_file_for_image (image, i + 1);
                if (file_image) {
-                       klass = mono_class_from_name (file_image, name_space, name);
-                       if (klass)
+                       klass = mono_class_from_name_checked (file_image, name_space, name, error);
+                       if (klass || !is_ok (error))
                                return klass;
                }
        }
@@ -7871,7 +7855,7 @@ search_modules (MonoImage *image, const char *name_space, const char *name)
 }
 
 static MonoClass *
-mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, MonoError *error, GHashTable* visited_images)
+mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, GHashTable* visited_images, MonoError *error)
 {
        GHashTable *nspace_table;
        MonoImage *loaded_image;
@@ -7904,8 +7888,11 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons
        if (get_class_from_name && image->tables [MONO_TABLE_EXPORTEDTYPE].rows == 0) {
                gboolean res = get_class_from_name (image, name_space, name, &klass);
                if (res) {
-                       if (!klass)
-                               klass = search_modules (image, name_space, name);
+                       if (!klass) {
+                               klass = search_modules (image, name_space, name, error);
+                               if (!is_ok (error))
+                                       return NULL;
+                       }
                        if (nested)
                                return klass ? return_nested_in (klass, nested) : NULL;
                        else
@@ -7928,15 +7915,15 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons
                for (i = 0; i < image->module_count; ++i) {
                        MonoImage *module = image->modules [i];
 
-                       klass = mono_class_from_name (module, name_space, name);
-                       if (klass)
+                       klass = mono_class_from_name_checked (module, name_space, name, error);
+                       if (klass || !is_ok (error))
                                return klass;
                }
        }
 
        if (!token) {
-               klass = search_modules (image, name_space, name);
-               if (klass)
+               klass = search_modules (image, name_space, name, error);
+               if (klass || !is_ok (error))
                        return klass;
        }
 
@@ -7957,7 +7944,7 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons
                        loaded_image = mono_assembly_load_module (image->assembly, impl >> MONO_IMPLEMENTATION_BITS);
                        if (!loaded_image)
                                return NULL;
-                       klass = mono_class_from_name_checked_aux (loaded_image, name_space, name, error, visited_images);
+                       klass = mono_class_from_name_checked_aux (loaded_image, name_space, name, visited_images, error);
                        if (nested)
                                return klass ? return_nested_in (klass, nested) : NULL;
                        return klass;
@@ -7970,9 +7957,9 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons
                        g_assert (image->references [assembly_idx - 1]);
                        if (image->references [assembly_idx - 1] == (gpointer)-1)
                                return NULL;                    
-                       klass = mono_class_from_name_checked_aux (image->references [assembly_idx - 1]->image, name_space, name, error, visited_images);
+                       klass = mono_class_from_name_checked_aux (image->references [assembly_idx - 1]->image, name_space, name, visited_images, error);
                        if (nested)
-                               return return_nested_in (klass, nested);
+                               return klass ? return_nested_in (klass, nested) : NULL;
                        return klass;
                } else {
                        g_assert_not_reached ();
@@ -7987,6 +7974,18 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons
        return klass;
 }
 
+/**
+ * mono_class_from_name_checked:
+ * @image: The MonoImage where the type is looked up in
+ * @name_space: the type namespace
+ * @name: the type short name.
+ *
+ * Obtains a MonoClass with a given namespace and a given name which
+ * is located in the given MonoImage.
+ *
+ * Works like mono_class_from_name, but error handling is tricky. It can return NULL and have no error
+ * set if the class was not found or it will return NULL and set the error if there was a loading error.
+ */
 MonoClass *
 mono_class_from_name_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error)
 {
@@ -7995,7 +7994,7 @@ mono_class_from_name_checked (MonoImage *image, const char* name_space, const ch
 
        visited_images = g_hash_table_new (g_direct_hash, g_direct_equal);
 
-       klass = mono_class_from_name_checked_aux (image, name_space, name, error, visited_images);
+       klass = mono_class_from_name_checked_aux (image, name_space, name, visited_images, error);
 
        g_hash_table_destroy (visited_images);
 
@@ -8022,13 +8021,61 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name
        MonoClass *klass;
 
        klass = mono_class_from_name_checked (image, name_space, name, &error);
-       if (!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); /* FIXME Don't swallow the error */
+
+       return klass;
+}
+
+/**
+ * mono_class_load_from_name:
+ * @image: The MonoImage where the type is looked up in
+ * @name_space: the type namespace
+ * @name: the type short name.
+ *
+ * This function works exactly like mono_class_from_name but it will abort if the class is not found.
+ * This function should be used by the runtime for critical types to which there's no way to recover but crash
+ * If they are missing. Thing of System.Object or System.String.
+ */
+MonoClass *
+mono_class_load_from_name (MonoImage *image, const char* name_space, const char *name)
+{
+       MonoError error;
+       MonoClass *klass;
+
+       klass = mono_class_from_name_checked (image, name_space, name, &error);
+       if (!klass)
+               g_error ("Runtime critical type %s.%s not found", name_space, name);
+       if (!mono_error_ok (&error))
+               g_error ("Could not load runtime critical type %s.%s due to %s", name_space, name, mono_error_get_message (&error));
+       return klass;
+}
+
+/**
+ * mono_class_try_load_from_name:
+ * @image: The MonoImage where the type is looked up in
+ * @name_space: the type namespace
+ * @name: the type short name.
+ *
+ * This function tries to load a type, returning the class was found or NULL otherwise.
+ * This function should be used by the runtime when probing for optional types, those that could have being linked out.
+ *
+ * Big design consideration. This function aborts if there was an error loading the type. This prevents us from missing
+ * a type that we would otherwise assume to be available but was not due some error.
+ *
+ */
+MonoClass*
+mono_class_try_load_from_name (MonoImage *image, const char* name_space, const char *name)
+{
+       MonoError error;
+       MonoClass *klass;
+
+       klass = mono_class_from_name_checked (image, name_space, name, &error);
+       if (!mono_error_ok (&error))
+               g_error ("Could not load runtime critical type %s.%s due to %s", name_space, name, mono_error_get_message (&error));
        return klass;
 }
 
+
 /**
  * mono_class_is_subclass_of:
  * @klass: class to probe if it is a subclass of another one
@@ -8038,11 +8085,11 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name
  * This method determines whether @klass is a subclass of @klassc.
  *
  * If the @check_interfaces flag is set, then if @klassc is an interface
- * this method return true if the @klass implements the interface or
+ * this method return TRUE if the @klass implements the interface or
  * if @klass is an interface, if one of its base classes is @klass.
  *
  * If @check_interfaces is false then, then if @klass is not an interface
- * then it returns true if the @klass is a subclass of @klassc.
+ * then it returns TRUE if the @klass is a subclass of @klassc.
  *
  * if @klass is an interface and @klassc is System.Object, then this function
  * return true.
@@ -8129,8 +8176,9 @@ mono_gparam_is_reference_conversible (MonoClass *target, MonoClass *candidate, g
  * @klass: the class to be assigned to
  * @oklass: the source class
  * 
- * Both klass and oklass must be instances of the same generic interface.
- * Return true if @klass can be assigned to a @klass variable
+ * Both @klass and @oklass must be instances of the same generic interface.
+ *
+ * Returns: TRUE if @klass can be assigned to a @klass variable
  */
 gboolean
 mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass, gboolean check_for_reference_conv)
@@ -8281,12 +8329,13 @@ mono_gparam_is_assignable_from (MonoClass *target, MonoClass *candidate)
  * @klass: the class to be assigned to
  * @oklass: the source class
  *
- * Return: true if an instance of object oklass can be assigned to an
+ * Returns: TRUE if an instance of object oklass can be assigned to an
  * instance of object @klass
  */
 gboolean
 mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
 {
+       MonoError error;
        /*FIXME this will cause a lot of irrelevant stuff to be loaded.*/
        if (!klass->inited)
                mono_class_init (klass);
@@ -8294,7 +8343,7 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
        if (!oklass->inited)
                mono_class_init (oklass);
 
-       if (klass->exception_type || oklass->exception_type)
+       if (mono_class_has_failure (klass) || mono_class_has_failure  (oklass))
                return FALSE;
 
        if (mono_type_is_generic_argument (&klass->byval_arg)) {
@@ -8320,12 +8369,18 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
                }
 
                /* interface_offsets might not be set for dynamic classes */
-               if (oklass->ref_info_handle && !oklass->interface_bitmap)
+               if (oklass->ref_info_handle && !oklass->interface_bitmap) {
                        /* 
                         * oklass might be a generic type parameter but they have 
                         * interface_offsets set.
                         */
-                       return mono_reflection_call_is_assignable_to (oklass, klass);
+                       gboolean result = mono_reflection_call_is_assignable_to (oklass, klass, &error);
+                       if (!is_ok (&error)) {
+                               mono_error_cleanup (&error);
+                               return FALSE;
+                       }
+                       return result;
+               }
                if (!oklass->interface_bitmap)
                        /* Happens with generic instances of not-yet created dynamic types */
                        return FALSE;
@@ -8333,7 +8388,6 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
                        return TRUE;
 
                if (mono_class_has_variant_generic_params (klass)) {
-                       MonoError error;
                        int i;
                        mono_class_setup_interfaces (oklass, &error);
                        if (!mono_error_ok (&error)) {
@@ -8863,6 +8917,8 @@ mono_install_get_class_from_name (MonoGetClassFromName func)
 /**
  * mono_class_get_image:
  *
+ * Use this method to get the `MonoImage*` where this class came from.
+ *
  * Returns: The image where this class is defined.
  */
 MonoImage*
@@ -8875,7 +8931,9 @@ mono_class_get_image (MonoClass *klass)
  * mono_class_get_element_class:
  * @klass: the MonoClass to act on
  *
- * Returns: The element class of an array or an enumeration.
+ * Use this function to get the element class of an array.
+ *
+ * Returns: The element class of an array.
  */
 MonoClass*
 mono_class_get_element_class (MonoClass *klass)
@@ -8887,7 +8945,10 @@ mono_class_get_element_class (MonoClass *klass)
  * mono_class_is_valuetype:
  * @klass: the MonoClass to act on
  *
- * Returns: true if the MonoClass represents a ValueType.
+ * Use this method to determine if the provided `MonoClass*` represents a value type,
+ * or a reference type.
+ *
+ * Returns: TRUE if the MonoClass represents a ValueType, FALSE if it represents a reference type.
  */
 gboolean
 mono_class_is_valuetype (MonoClass *klass)
@@ -8899,7 +8960,9 @@ mono_class_is_valuetype (MonoClass *klass)
  * mono_class_is_enum:
  * @klass: the MonoClass to act on
  *
- * Returns: true if the MonoClass represents an enumeration.
+ * Use this function to determine if the provided `MonoClass*` represents an enumeration.
+ *
+ * Returns: TRUE if the MonoClass represents an enumeration.
  */
 gboolean
 mono_class_is_enum (MonoClass *klass)
@@ -8911,6 +8974,8 @@ mono_class_is_enum (MonoClass *klass)
  * mono_class_enum_basetype:
  * @klass: the MonoClass to act on
  *
+ * Use this function to get the underlying type for an enumeration value.
+ * 
  * Returns: The underlying type representation for an enumeration.
  */
 MonoType*
@@ -8939,6 +9004,10 @@ mono_class_get_parent (MonoClass *klass)
  * mono_class_get_nesting_type:
  * @klass: the MonoClass to act on
  *
+ * Use this function to obtain the class that the provided `MonoClass*` is nested on.
+ *
+ * If the return is NULL, this indicates that this class is not nested.
+ *
  * Returns: The container type where this type is nested or NULL if this type is not a nested type.
  */
 MonoClass*
@@ -9111,7 +9180,7 @@ mono_class_get_fields (MonoClass* klass, gpointer *iter)
                return NULL;
        if (!*iter) {
                mono_class_setup_fields_locking (klass);
-               if (klass->exception_type)
+               if (mono_class_has_failure (klass))
                        return NULL;
                /* start from the first */
                if (klass->field.count) {
@@ -9472,7 +9541,7 @@ mono_class_get_nested_types (MonoClass* klass, gpointer *iter)
  * mono_class_is_delegate
  * @klass: the MonoClass to act on
  *
- * Returns: true if the MonoClass represents a System.Delegate.
+ * Returns: TRUE if the MonoClass represents a System.Delegate.
  */
 mono_bool
 mono_class_is_delegate (MonoClass *klass)
@@ -9485,7 +9554,7 @@ mono_class_is_delegate (MonoClass *klass)
  * @klass: The MonoClass to act on
  * @interface: The interface to check if @klass implements.
  *
- * Returns: true if @klass implements @interface.
+ * Returns: TRUE if @klass implements @interface.
  */
 mono_bool
 mono_class_implements_interface (MonoClass* klass, MonoClass* iface)
@@ -9900,7 +9969,7 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p
 gboolean
 mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data)
 {
-       if (klass->exception_type)
+       if (mono_class_has_failure (klass))
                return FALSE;
 
        mono_loader_lock ();
@@ -9974,7 +10043,7 @@ mono_class_get_exception_for_failure (MonoClass *klass)
 {
        gpointer exception_data = mono_class_get_exception_data (klass);
 
-       switch (klass->exception_type) {
+       switch (mono_class_get_failure(klass)) {
        case MONO_EXCEPTION_TYPE_LOAD: {
                MonoString *name;
                MonoException *ex;
@@ -10013,6 +10082,9 @@ mono_class_get_exception_for_failure (MonoClass *klass)
        case MONO_EXCEPTION_BAD_IMAGE: {
                return mono_get_exception_bad_image_format ((const char *)exception_data);
        }
+       case MONO_EXCEPTION_INVALID_PROGRAM: {
+               return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", "");
+       }
        default: {
                MonoLoaderError *error;
                MonoException *ex;
@@ -10300,7 +10372,7 @@ can_access_member (MonoClass *access_klass, MonoClass *member_klass, MonoClass*
  *
  * Used to determine if a method is allowed to access the specified field.
  *
- * Returns: true if the given @method is allowed to access the @field while following
+ * Returns: TRUE if the given @method is allowed to access the @field while following
  * the accessibility rules of the CLI.
  */
 gboolean
@@ -10327,7 +10399,7 @@ mono_method_can_access_field (MonoMethod *method, MonoClassField *field)
  *
  * Used to determine if the @method is allowed to access the specified @called method.
  *
- * Returns: true if the given @method is allowed to invoke the @called while following
+ * Returns: TRUE if the given @method is allowed to invoke the @called while following
  * the accessibility rules of the CLI.
  */
 gboolean
@@ -10670,14 +10742,12 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
                if (!mono_error_ok (error)) {
                        char *err_msg = g_strdup_printf ("Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
-                       g_free (err_msg);
                }
 
                field->type = mono_class_inflate_generic_type_no_copy (image, gtype, mono_class_get_context (klass), error);
                if (!mono_error_ok (error)) {
                        char *err_msg = g_strdup_printf ("Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
-                       g_free (err_msg);
                }
        } else {
                const char *sig;
@@ -10699,8 +10769,8 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
                mono_metadata_decode_table_row (image, MONO_TABLE_FIELD, idx, cols, MONO_FIELD_SIZE);
 
                if (!mono_verifier_verify_field_signature (image, cols [MONO_FIELD_SIGNATURE], NULL)) {
-                       mono_error_set_type_load_class (error, klass, "Could not verify field %s signature", field->name);
-                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       mono_error_set_type_load_class (error, klass, "Could not verify field %s signature", field->name);;
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup (mono_error_get_message (error)));
                        return;
                }
 
@@ -10709,9 +10779,12 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
                mono_metadata_decode_value (sig, &sig);
                /* FIELD signature == 0x06 */
                g_assert (*sig == 0x06);
-               field->type = mono_metadata_parse_type_full (image, container, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
-               if (!field->type)
-                       mono_class_set_failure_from_loader_error (klass, error, g_strdup_printf ("Could not load field %s type", field->name));
+
+               field->type = mono_metadata_parse_type_checked (image, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
+               if (!field->type) {
+                       char *err_msg = g_strdup_printf ("Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+               }
        }
 }
 
@@ -10800,3 +10873,5 @@ mono_class_full_name (MonoClass *klass)
        return mono_type_full_name (&klass->byval_arg);
 }
 
+/* Declare all shared lazy type lookup functions */
+GENERATE_TRY_GET_CLASS_WITH_CACHE (safehandle, System.Runtime.InteropServices, SafeHandle)