First set of licensing changes
[mono.git] / mono / metadata / class.c
index d3ee6458d03056d8e2a54a1cf8014535f56e73d8..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
@@ -150,14 +151,14 @@ disable_gclass_recording (gclass_record_func func, void *user_data)
        }
 }
 
-/*
+/**
  * mono_class_from_typeref:
  * @image: a MonoImage
  * @type_token: a TypeRef token
  *
  * Creates the MonoClass* structure representing the type defined by
  * the typeref token valid inside @image.
- * Returns: the MonoClass* representing the typeref token, NULL ifcould
+ * Returns: The MonoClass* representing the typeref token, NULL ifcould
  * not be loaded.
  */
 MonoClass *
@@ -169,6 +170,19 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token)
        return klass;
 }
 
+/**
+ * mono_class_from_typeref_checked:
+ * @image: a MonoImage
+ * @type_token: a TypeRef token
+ * @error: error return code, if any.
+ *
+ * Creates the MonoClass* structure representing the type defined by
+ * the typeref token valid inside @image.
+ *
+ * Returns: The MonoClass* representing the typeref token, NULL if it could
+ * not be loaded with the @error value filled with the information about the
+ * error.
+ */
 MonoClass *
 mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError *error)
 {
@@ -551,7 +565,7 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed,
  * @format: the format for the return string.
  *
  * 
- * Returns: the string representation in a number of formats:
+ * Returns: The string representation in a number of formats:
  *
  * if format is MONO_TYPE_NAME_FORMAT_REFLECTION, the return string is
  * returned in the formatrequired by System.Reflection, this is the
@@ -580,7 +594,7 @@ mono_type_get_name_full (MonoType *type, MonoTypeNameFormat format)
  * mono_type_get_full_name:
  * @class: a class
  *
- * Returns: the string representation for type as required by System.Reflection.
+ * Returns: The string representation for type as required by System.Reflection.
  * The inverse of mono_reflection_parse_type ().
  */
 char *
@@ -593,7 +607,7 @@ mono_type_get_full_name (MonoClass *klass)
  * mono_type_get_name:
  * @type: a type
  *
- * Returns: the string representation for type as it would be represented in IL code.
+ * Returns: The string representation for type as it would be represented in IL code.
  */
 char*
 mono_type_get_name (MonoType *type)
@@ -605,7 +619,7 @@ mono_type_get_name (MonoType *type)
  * mono_type_get_underlying_type:
  * @type: a type
  *
- * Returns: the MonoType for the underlying integer type if @type
+ * Returns: The MonoType for the underlying integer type if @type
  * is an enum and byref is false, otherwise the type itself.
  */
 MonoType*
@@ -618,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.
  *
@@ -881,7 +895,7 @@ mono_class_inflate_generic_type_with_mempool (MonoImage *image, MonoType *type,
  * If @type is a generic type and @context is not NULL, instantiate it using the 
  * generics context @context.
  *
- * Returns: the instantiated type or a copy of @type. The returned MonoType is allocated
+ * Returns: The instantiated type or a copy of @type. The returned MonoType is allocated
  * on the heap and is owned by the caller. Returns NULL on error.
  *
  * @deprecated Please use mono_class_inflate_generic_type_checked instead
@@ -892,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;
 }
 
@@ -909,7 +919,7 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context)
  * If @type is a generic type and @context is not NULL, instantiate it using the 
  * generics context @context.
  *
- * Returns: the instantiated type or a copy of @type. The returned MonoType is allocated
+ * Returns: The instantiated type or a copy of @type. The returned MonoType is allocated
  * on the heap and is owned by the caller.
  */
 MonoType*
@@ -942,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)
 {
@@ -956,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)
@@ -1009,7 +1006,7 @@ fail:
  *
  * Instantiate the generic method @method using the generics context @context.
  *
- * Returns: the new instantiated method
+ * Returns: The new instantiated method
  */
 MonoMethod *
 mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *context)
@@ -1337,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);
@@ -1372,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;
        }
@@ -1488,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;
@@ -1557,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;
 
@@ -1572,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;
        }
 
@@ -1605,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;
@@ -1688,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;
                                        }
@@ -1726,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))))
@@ -1812,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:
@@ -1824,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;
@@ -1905,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:
@@ -1920,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;
                        }
@@ -1981,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;
@@ -2070,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;
        }
@@ -2089,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;
 
@@ -2178,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;
@@ -2361,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];
@@ -2383,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) {
@@ -2432,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];
        }
@@ -2478,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;
                }
@@ -2510,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;
                }
 
@@ -2611,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;
                }
@@ -2651,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;
                        }
@@ -2768,14 +2770,14 @@ mono_unload_interface_id (MonoClass *klass)
        }
 }
 
-/*
+/**
  * mono_get_unique_iid:
  * @class: interface
  *
  * Assign a unique integer ID to the interface represented by @class.
  * The ID will positive and as small as possible.
  * LOCKING: Acquires the classes lock.
- * Returns: the new ID.
+ * Returns: The new ID.
  */
 static guint
 mono_get_unique_iid (MonoClass *klass)
@@ -2850,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;
                }
@@ -2898,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
@@ -3093,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");
        }
 
@@ -3285,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) {
@@ -3407,7 +3409,7 @@ set_interface_and_offset (int num_ifaces, MonoClass **interfaces_full, int *inte
  * the size of the buffer.
  * This compression algorithm assumes the bits set in the bitmap are
  * few and far between, like in interface bitmaps.
- * Returns: the size of the compressed bitmap in bytes.
+ * Returns: The size of the compressed bitmap in bytes.
  */
 int
 mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size)
@@ -3449,7 +3451,7 @@ mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size)
  * be already checked for being smaller than the maximum id encoded in the
  * bitmap.
  *
- * Returns: a non-zero value if bit @id is set in the bitmap @bitmap,
+ * Returns: A non-zero value if bit @id is set in the bitmap @bitmap,
  * #FALSE otherwise.
  */
 int
@@ -3753,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;
        }
@@ -3800,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;
@@ -3815,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))
@@ -3850,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. */
@@ -4209,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);
@@ -4333,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);
@@ -4372,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;
                }
@@ -4428,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,
@@ -4490,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;
        }
        
@@ -4505,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)
@@ -4552,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;
                                }
                                
@@ -4573,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"));
                                        }
@@ -4668,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) 
@@ -4843,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;
@@ -4939,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)) {
@@ -5099,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) {
@@ -5130,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;
                }
@@ -5148,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;
                }
@@ -5183,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;
                }
                                
@@ -5237,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;
                }
@@ -5269,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) {
@@ -5288,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;
                }
@@ -5297,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;
                        }
@@ -5316,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 ();
@@ -5335,7 +5345,7 @@ mono_class_init (MonoClass *klass)
 
        mono_loader_unlock ();
 
-       return klass->exception_type == MONO_EXCEPTION_NONE;
+       return !mono_class_has_failure (klass);
 }
 
 /*
@@ -5370,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];
@@ -5725,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
@@ -6208,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 );
        }
@@ -6252,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);
@@ -6549,6 +6543,12 @@ mono_fnptr_class_get (MonoMethodSignature *sig)
        return result;
 }
 
+/**
+ * mono_class_from_mono_type:
+ * @type: describes the type to return
+ *
+ * This returns a MonoClass for the specified MonoType, the value is never NULL.
+ */
 MonoClass *
 mono_class_from_mono_type (MonoType *type)
 {
@@ -6609,7 +6609,9 @@ mono_class_from_mono_type (MonoType *type)
                g_warning ("mono_class_from_mono_type: implement me 0x%02x\n", type->type);
                g_assert_not_reached ();
        }
-       
+
+       // Yes, this returns NULL, even if it is documented as not doing so, but there
+       // is no way for the code to make it this far, due to the assert above.
        return NULL;
 }
 
@@ -6670,7 +6672,7 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec, MonoGeneri
  * @rank: the dimension of the array class
  * @bounded: whenever the array has non-zero bounds
  *
- * Returns: a class object describing the array with element type @element_type and 
+ * Returns: A class object describing the array with element type @element_type and 
  * dimension @rank. 
  */
 MonoClass *
@@ -6726,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;
@@ -6763,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");
@@ -6780,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;
@@ -6866,7 +6868,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
  * @element_class: element class 
  * @rank: the dimension of the array class
  *
- * Returns: a class object describing the array with element type @element_type and 
+ * Returns: A class object describing the array with element type @element_type and 
  * dimension @rank. 
  */
 MonoClass *
@@ -6878,8 +6880,10 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
 /**
  * mono_class_instance_size:
  * @klass: a class 
- * 
- * Returns: the size of an object instance
+ *
+ * Use to get the size of a class in bytes.
+ *
+ * Returns: The size of an object instance
  */
 gint32
 mono_class_instance_size (MonoClass *klass)
@@ -6893,7 +6897,9 @@ mono_class_instance_size (MonoClass *klass)
 /**
  * mono_class_min_align:
  * @klass: a class 
- * 
+ *
+ * Use to get the computed minimum alignment requirements for the specified class.
+ *
  * Returns: minimm alignment requirements 
  */
 gint32
@@ -6936,7 +6942,7 @@ mono_class_value_size      (MonoClass *klass, guint32 *align)
  * mono_class_data_size:
  * @klass: a class 
  * 
- * Returns: the size of the static class data
+ * Returns: The size of the static class data
  */
 gint32
 mono_class_data_size (MonoClass *klass)
@@ -6964,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) {
@@ -7019,7 +7025,7 @@ mono_class_get_field (MonoClass *klass, guint32 field_token)
  *
  * Search the class @klass and it's parents for a field with the name @name.
  * 
- * Returns: the MonoClassField pointer of the named field or NULL
+ * Returns: The MonoClassField pointer of the named field or NULL
  */
 MonoClassField *
 mono_class_get_field_from_name (MonoClass *klass, const char *name)
@@ -7038,7 +7044,7 @@ mono_class_get_field_from_name (MonoClass *klass, const char *name)
  * If @klass is an inflated generic type, the type comparison is done with the equivalent field
  * of its generic type definition.
  *
- * Returns: the MonoClassField pointer of the named field or NULL
+ * Returns: The MonoClassField pointer of the named field or NULL
  */
 MonoClassField *
 mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoType *type)
@@ -7046,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) {
@@ -7075,7 +7081,7 @@ mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoTyp
  * Get the token of a field. Note that the tokesn is only valid for the image
  * the field was loaded from. Don't use this function for fields in dynamic types.
  * 
- * Returns: the token representing the field in the image it was loaded from.
+ * Returns: The token representing the field in the image it was loaded from.
  */
 guint32
 mono_class_get_field_token (MonoClassField *field)
@@ -7227,6 +7233,15 @@ mono_class_get_event_token (MonoEvent *event)
        return 0;
 }
 
+/**
+ * mono_class_get_property_from_name:
+ * @klass: a class
+ * @name: name of the property to lookup in the specified class
+ *
+ * Use this method to lookup a property in a class
+ * Returns: the MonoProperty with the given name, or NULL if the property
+ * does not exist on the @klass.
+ */
 MonoProperty*
 mono_class_get_property_from_name (MonoClass *klass, const char *name)
 {
@@ -7242,6 +7257,12 @@ mono_class_get_property_from_name (MonoClass *klass, const char *name)
        return NULL;
 }
 
+/**
+ * mono_class_get_property_token:
+ * @prop: MonoProperty to query
+ *
+ * Returns: The ECMA token for the specified property.
+ */
 guint32
 mono_class_get_property_token (MonoProperty *prop)
 {
@@ -7385,7 +7406,7 @@ mono_assembly_name_from_token (MonoImage *image, guint32 type_token)
  * @context: the generic context used to evaluate generic instantiations in
  * @deprecated: Functions that expose MonoGenericContext are going away in mono 4.0
  *
- * Returns: the MonoClass that represents @type_token in @image
+ * Returns: The MonoClass that represents @type_token in @image
  */
 MonoClass *
 mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context)
@@ -7421,7 +7442,7 @@ mono_class_get_and_inflate_typespec_checked (MonoImage *image, guint32 type_toke
  * @type_token: the token for the class
  * @error: error object to return any error
  *
- * Returns: the MonoClass that represents @type_token in @image
+ * Returns: The MonoClass that represents @type_token in @image, or NULL on error.
  */
 MonoClass *
 mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error)
@@ -7476,7 +7497,7 @@ done:
  *
  * This functions exists to fullfill the fact that sometimes it's desirable to have access to the 
  * 
- * Returns: the MonoType that represents @type_token in @image
+ * Returns: The MonoType that represents @type_token in @image
  */
 MonoType *
 mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error)
@@ -7526,7 +7547,13 @@ mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext
        return type;
 }
 
-
+/**
+ * mono_class_get:
+ * @image: image where the class token will be looked up.
+ * @type_token: a type token from the image
+ *
+ * Returns the MonoClass with the given @type_token on the @image
+ */
 MonoClass *
 mono_class_get (MonoImage *image, guint32 type_token)
 {
@@ -7680,7 +7707,7 @@ find_nocase (gpointer key, gpointer value, gpointer user_data)
  * @image: The MonoImage where the type is looked up in
  * @name_space: the type namespace
  * @name: the type short name.
- * @deprecated: use the _checked variant
+ * @deprecated: use the mono_class_from_name_case_checked variant instead.
  *
  * Obtains a MonoClass with a given namespace and a given name which
  * is located in the given MonoImage.   The namespace and name
@@ -7691,12 +7718,28 @@ 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;
 }
 
+/**
+ * mono_class_from_name_case:
+ * @image: The MonoImage where the type is looked up in
+ * @name_space: the type namespace
+ * @name: the type short name.
+ * @error: if 
+ *
+ * Obtains a MonoClass with a given namespace and a given name which
+ * is located in the given MonoImage.   The namespace and name
+ * lookups are case insensitive.
+ *
+ * Returns: The MonoClass if the given namespace and name were found, or NULL if it
+ * was not found.   The @error object will contain information about the problem
+ * in that case.
+ */
 MonoClass *
-mono_class_from_name_case_checked (MonoImage *image, const charname_space, const char *name, MonoError *error)
+mono_class_from_name_case_checked (MonoImage *image, const char *name_space, const char *name, MonoError *error)
 {
        MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEDEF];
        guint32 cols [MONO_TYPEDEF_SIZE];
@@ -7779,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.
@@ -7800,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;
                }
        }
@@ -7810,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;
@@ -7843,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
@@ -7867,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;
        }
 
@@ -7896,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;
@@ -7909,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 ();
@@ -7926,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)
 {
@@ -7934,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);
 
@@ -7961,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
@@ -7977,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.
@@ -8068,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)
@@ -8220,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);
@@ -8233,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)) {
@@ -8259,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;
@@ -8272,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)) {
@@ -8494,7 +8609,7 @@ mono_class_is_assignable_from_slow (MonoClass *target, MonoClass *candidate)
  * mono_class_get_cctor:
  * @klass: A MonoClass pointer
  *
- * Returns: the static constructor of @klass if it exists, NULL otherwise.
+ * Returns: The static constructor of @klass if it exists, NULL otherwise.
  */
 MonoMethod*
 mono_class_get_cctor (MonoClass *klass)
@@ -8530,7 +8645,7 @@ mono_class_get_cctor (MonoClass *klass)
  * mono_class_get_finalizer:
  * @klass: The MonoClass pointer
  *
- * Returns: the finalizer method of @klass if it exists, NULL otherwise.
+ * Returns: The finalizer method of @klass if it exists, NULL otherwise.
  */
 MonoMethod*
 mono_class_get_finalizer (MonoClass *klass)
@@ -8578,7 +8693,7 @@ mono_class_needs_cctor_run (MonoClass *klass, MonoMethod *caller)
  * mono_class_array_element_size:
  * @klass: 
  *
- * Returns: the number of bytes an element of type @klass
+ * Returns: The number of bytes an element of type @klass
  * uses when stored into an array.
  */
 gint32
@@ -8642,7 +8757,7 @@ handle_enum:
  * mono_array_element_size:
  * @ac: pointer to a #MonoArrayClass
  *
- * Returns: the size of single array element.
+ * Returns: The size of single array element.
  */
 gint32
 mono_array_element_size (MonoClass *ac)
@@ -8799,6 +8914,13 @@ mono_install_get_class_from_name (MonoGetClassFromName func)
        get_class_from_name = 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*
 mono_class_get_image (MonoClass *klass)
 {
@@ -8809,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)
@@ -8821,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)
@@ -8833,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)
@@ -8845,7 +8974,9 @@ mono_class_is_enum (MonoClass *klass)
  * mono_class_enum_basetype:
  * @klass: the MonoClass to act on
  *
- * Returns: the underlying type representation for an enumeration.
+ * Use this function to get the underlying type for an enumeration value.
+ * 
+ * Returns: The underlying type representation for an enumeration.
  */
 MonoType*
 mono_class_enum_basetype (MonoClass *klass)
@@ -8861,7 +8992,7 @@ mono_class_enum_basetype (MonoClass *klass)
  * mono_class_get_parent
  * @klass: the MonoClass to act on
  *
- * Returns: the parent class for this class.
+ * Returns: The parent class for this class.
  */
 MonoClass*
 mono_class_get_parent (MonoClass *klass)
@@ -8870,10 +9001,14 @@ mono_class_get_parent (MonoClass *klass)
 }
 
 /**
- * mono_class_get_nesting_type;
+ * mono_class_get_nesting_type:
  * @klass: the MonoClass to act on
  *
- * Returns: the container type where this type is nested or NULL if this type is not a nested type.
+ * 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*
 mono_class_get_nesting_type (MonoClass *klass)
@@ -8885,7 +9020,7 @@ mono_class_get_nesting_type (MonoClass *klass)
  * mono_class_get_rank:
  * @klass: the MonoClass to act on
  *
- * Returns: the rank for the array (the number of dimensions).
+ * Returns: The rank for the array (the number of dimensions).
  */
 int
 mono_class_get_rank (MonoClass *klass)
@@ -8901,7 +9036,7 @@ mono_class_get_rank (MonoClass *klass)
  * see the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the
  * different values.
  *
- * Returns: the flags from the TypeDef table.
+ * Returns: The flags from the TypeDef table.
  */
 guint32
 mono_class_get_flags (MonoClass *klass)
@@ -8913,7 +9048,7 @@ mono_class_get_flags (MonoClass *klass)
  * mono_class_get_name
  * @klass: the MonoClass to act on
  *
- * Returns: the name of the class.
+ * Returns: The name of the class.
  */
 const char*
 mono_class_get_name (MonoClass *klass)
@@ -8925,7 +9060,7 @@ mono_class_get_name (MonoClass *klass)
  * mono_class_get_namespace:
  * @klass: the MonoClass to act on
  *
- * Returns: the namespace of the class.
+ * Returns: The namespace of the class.
  */
 const char*
 mono_class_get_namespace (MonoClass *klass)
@@ -8939,7 +9074,7 @@ mono_class_get_namespace (MonoClass *klass)
  *
  * This method returns the internal Type representation for the class.
  *
- * Returns: the MonoType from the class.
+ * Returns: The MonoType from the class.
  */
 MonoType*
 mono_class_get_type (MonoClass *klass)
@@ -8948,12 +9083,12 @@ mono_class_get_type (MonoClass *klass)
 }
 
 /**
- * mono_class_get_type_token
+ * mono_class_get_type_token:
  * @klass: the MonoClass to act on
  *
  * This method returns type token for the class.
  *
- * Returns: the type token for the class.
+ * Returns: The type token for the class.
  */
 guint32
 mono_class_get_type_token (MonoClass *klass)
@@ -8977,7 +9112,7 @@ mono_class_get_byref_type (MonoClass *klass)
  * mono_class_num_fields:
  * @klass: the MonoClass to act on
  *
- * Returns: the number of static and instance fields in the class.
+ * Returns: The number of static and instance fields in the class.
  */
 int
 mono_class_num_fields (MonoClass *klass)
@@ -8989,7 +9124,7 @@ mono_class_num_fields (MonoClass *klass)
  * mono_class_num_methods:
  * @klass: the MonoClass to act on
  *
- * Returns: the number of methods in the class.
+ * Returns: The number of methods in the class.
  */
 int
 mono_class_num_methods (MonoClass *klass)
@@ -9001,7 +9136,7 @@ mono_class_num_methods (MonoClass *klass)
  * mono_class_num_properties
  * @klass: the MonoClass to act on
  *
- * Returns: the number of properties in the class.
+ * Returns: The number of properties in the class.
  */
 int
 mono_class_num_properties (MonoClass *klass)
@@ -9015,7 +9150,7 @@ mono_class_num_properties (MonoClass *klass)
  * mono_class_num_events:
  * @klass: the MonoClass to act on
  *
- * Returns: the number of events in the class.
+ * Returns: The number of events in the class.
  */
 int
 mono_class_num_events (MonoClass *klass)
@@ -9045,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) {
@@ -9406,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)
@@ -9419,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)
@@ -9431,7 +9566,7 @@ mono_class_implements_interface (MonoClass* klass, MonoClass* iface)
  * mono_field_get_name:
  * @field: the MonoClassField to act on
  *
- * Returns: the name of the field.
+ * Returns: The name of the field.
  */
 const char*
 mono_field_get_name (MonoClassField *field)
@@ -9493,7 +9628,7 @@ mono_field_get_parent (MonoClassField *field)
  * The metadata flags for a field are encoded using the
  * FIELD_ATTRIBUTE_* constants.  See the tabledefs.h file for details.
  *
- * Returns: the flags for the field.
+ * Returns: The flags for the field.
  */
 guint32
 mono_field_get_flags (MonoClassField *field)
@@ -9504,10 +9639,10 @@ mono_field_get_flags (MonoClassField *field)
 }
 
 /**
- * mono_field_get_offset;
+ * mono_field_get_offset:
  * @field: the MonoClassField to act on
  *
- * Returns: the field offset.
+ * Returns: The field offset.
  */
 guint32
 mono_field_get_offset (MonoClassField *field)
@@ -9549,10 +9684,10 @@ mono_field_get_rva (MonoClassField *field)
 }
 
 /**
- * mono_field_get_data;
+ * mono_field_get_data:
  * @field: the MonoClassField to act on
  *
- * Returns: pointer to the metadata constant value or to the field
+ * Returns: pointer to the metadata constant value or to the field
  * data if it has an RVA flag.
  */
 const char *
@@ -9573,7 +9708,7 @@ mono_field_get_data (MonoClassField *field)
  * mono_property_get_name: 
  * @prop: the MonoProperty to act on
  *
- * Returns: the name of the property
+ * Returns: The name of the property
  */
 const char*
 mono_property_get_name (MonoProperty *prop)
@@ -9585,7 +9720,7 @@ mono_property_get_name (MonoProperty *prop)
  * mono_property_get_set_method
  * @prop: the MonoProperty to act on.
  *
- * Returns: the setter method of the property (A MonoMethod)
+ * Returns: The setter method of the property (A MonoMethod)
  */
 MonoMethod*
 mono_property_get_set_method (MonoProperty *prop)
@@ -9597,7 +9732,7 @@ mono_property_get_set_method (MonoProperty *prop)
  * mono_property_get_get_method
  * @prop: the MonoProperty to act on.
  *
- * Returns: the setter method of the property (A MonoMethod)
+ * Returns: The setter method of the property (A MonoMethod)
  */
 MonoMethod*
 mono_property_get_get_method (MonoProperty *prop)
@@ -9609,7 +9744,7 @@ mono_property_get_get_method (MonoProperty *prop)
  * mono_property_get_parent:
  * @prop: the MonoProperty to act on.
  *
- * Returns: the MonoClass where the property was defined.
+ * Returns: The MonoClass where the property was defined.
  */
 MonoClass*
 mono_property_get_parent (MonoProperty *prop)
@@ -9624,7 +9759,7 @@ mono_property_get_parent (MonoProperty *prop)
  * The metadata flags for a property are encoded using the
  * PROPERTY_ATTRIBUTE_* constants.  See the tabledefs.h file for details.
  *
- * Returns: the flags for the property.
+ * Returns: The flags for the property.
  */
 guint32
 mono_property_get_flags (MonoProperty *prop)
@@ -9636,7 +9771,7 @@ mono_property_get_flags (MonoProperty *prop)
  * mono_event_get_name:
  * @event: the MonoEvent to act on
  *
- * Returns: the name of the event.
+ * Returns: The name of the event.
  */
 const char*
 mono_event_get_name (MonoEvent *event)
@@ -9648,7 +9783,7 @@ mono_event_get_name (MonoEvent *event)
  * mono_event_get_add_method:
  * @event: The MonoEvent to act on.
  *
- * Returns: the @add' method for the event (a MonoMethod).
+ * Returns: The @add' method for the event (a MonoMethod).
  */
 MonoMethod*
 mono_event_get_add_method (MonoEvent *event)
@@ -9660,7 +9795,7 @@ mono_event_get_add_method (MonoEvent *event)
  * mono_event_get_remove_method:
  * @event: The MonoEvent to act on.
  *
- * Returns: the @remove method for the event (a MonoMethod).
+ * Returns: The @remove method for the event (a MonoMethod).
  */
 MonoMethod*
 mono_event_get_remove_method (MonoEvent *event)
@@ -9672,7 +9807,7 @@ mono_event_get_remove_method (MonoEvent *event)
  * mono_event_get_raise_method:
  * @event: The MonoEvent to act on.
  *
- * Returns: the @raise method for the event (a MonoMethod).
+ * Returns: The @raise method for the event (a MonoMethod).
  */
 MonoMethod*
 mono_event_get_raise_method (MonoEvent *event)
@@ -9684,7 +9819,7 @@ mono_event_get_raise_method (MonoEvent *event)
  * mono_event_get_parent:
  * @event: the MonoEvent to act on.
  *
- * Returns: the MonoClass where the event is defined.
+ * Returns: The MonoClass where the event is defined.
  */
 MonoClass*
 mono_event_get_parent (MonoEvent *event)
@@ -9699,7 +9834,7 @@ mono_event_get_parent (MonoEvent *event)
  * The metadata flags for an event are encoded using the
  * EVENT_* constants.  See the tabledefs.h file for details.
  *
- * Returns: the flags for the event.
+ * Returns: The flags for the event.
  */
 guint32
 mono_event_get_flags (MonoEvent *event)
@@ -9834,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 ();
@@ -9908,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;
@@ -9947,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;
@@ -10227,6 +10365,16 @@ can_access_member (MonoClass *access_klass, MonoClass *member_klass, MonoClass*
        return FALSE;
 }
 
+/**
+ * mono_method_can_access_field:
+ * @method: Method that will attempt to access the field
+ * @field: the field to access
+ *
+ * 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
+ * the accessibility rules of the CLI.
+ */
 gboolean
 mono_method_can_access_field (MonoMethod *method, MonoClassField *field)
 {
@@ -10244,6 +10392,16 @@ mono_method_can_access_field (MonoMethod *method, MonoClassField *field)
        return can;
 }
 
+/**
+ * mono_method_can_access_method:
+ * @method: Method that will attempt to access the other method
+ * @called: the method that we want to probe for accessibility.
+ *
+ * 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
+ * the accessibility rules of the CLI.
+ */
 gboolean
 mono_method_can_access_method (MonoMethod *method, MonoMethod *called)
 {
@@ -10584,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;
@@ -10613,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;
                }
 
@@ -10623,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);
+               }
        }
 }
 
@@ -10714,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)