Merge pull request #1857 from slluis/fix-assembly-resolver
[mono.git] / mono / metadata / class.c
index 93853e594c1860a881bb3fabfbf4c485565b33eb..ca7567985ff3193344445353b7920d60b46a516c 100644 (file)
@@ -47,6 +47,7 @@
 MonoStats mono_stats;
 
 gboolean mono_print_vtable = FALSE;
+gboolean mono_align_small_structs = FALSE;
 
 /* Statistics */
 guint32 inflated_classes, inflated_classes_size, inflated_methods_size;
@@ -196,13 +197,13 @@ mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError
                The defacto behavior is that it's just a typedef in disguise.
                */
                /* a typedef in disguise */
-               res = mono_class_from_name (image, nspace, name); /*FIXME proper error handling*/
+               res = mono_class_from_name_checked (image, nspace, name, error);
                goto done;
 
        case MONO_RESOLUTION_SCOPE_MODULEREF:
                module = mono_image_load_module (image, idx);
                if (module)
-                       res = mono_class_from_name (module, nspace, name); /*FIXME proper error handling*/
+                       res = mono_class_from_name_checked (module, nspace, name, error);
                goto done;
 
        case MONO_RESOLUTION_SCOPE_TYPEREF: {
@@ -266,15 +267,20 @@ mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError
                return NULL;
        }
 
-       res = mono_class_from_name (image->references [idx - 1]->image, nspace, name);
+       res = mono_class_from_name_checked (image->references [idx - 1]->image, nspace, name, error);
 
 done:
        /* Generic case, should be avoided for when a better error is possible. */
        if (!res && mono_error_ok (error)) {
-               char *name = mono_class_name_from_token (image, type_token);
-               char *assembly = mono_assembly_name_from_token (image, type_token);
-               mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token);
+               if (mono_loader_get_last_error ()) { /*FIXME plug the above to not leak errors*/
+                       mono_error_set_from_loader_error (error);
+               } else {
+                       char *name = mono_class_name_from_token (image, type_token);
+                       char *assembly = mono_assembly_name_from_token (image, type_token);
+                       mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token);
+               }
        }
+       g_assert (!mono_loader_get_last_error ());
        return res;
 }
 
@@ -611,8 +617,9 @@ is_valid_generic_argument (MonoType *type)
        case MONO_TYPE_VOID:
        //case MONO_TYPE_TYPEDBYREF:
                return FALSE;
+       default:
+               return TRUE;
        }
-       return TRUE;
 }
 
 static MonoType*
@@ -966,6 +973,12 @@ mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *conte
        return mono_class_inflate_generic_method_full (method, NULL, context);
 }
 
+MonoMethod *
+mono_class_inflate_generic_method_checked (MonoMethod *method, MonoGenericContext *context, MonoError *error)
+{
+       return mono_class_inflate_generic_method_full_checked (method, NULL, context, error);
+}
+
 /**
  * mono_class_inflate_generic_method_full:
  *
@@ -1077,6 +1090,9 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
                else if (iresult->declaring->klass->generic_class)
                        iresult->context.class_inst = iresult->declaring->klass->generic_class->context.class_inst;
        }
+       /* This can happen with some callers like mono_object_get_virtual_method () */
+       if (!iresult->declaring->klass->generic_container && !iresult->declaring->klass->generic_class)
+               iresult->context.class_inst = NULL;
 
        cached = mono_method_inflated_lookup (iresult, FALSE);
        if (cached) {
@@ -1338,8 +1354,9 @@ mono_type_has_exceptions (MonoType *type)
                return type->data.array->eklass->exception_type;
        case MONO_TYPE_GENERICINST:
                return mono_generic_class_get_class (type->data.generic_class)->exception_type;
+       default:
+               return FALSE;
        }
-       return FALSE;
 }
 
 /*
@@ -1559,8 +1576,8 @@ mono_class_setup_fields (MonoClass *class)
        explicit_size = mono_metadata_packing_from_typedef (class->image, class->type_token, &packing_size, &real_size);
 
        if (explicit_size) {
-               if ((packing_size & 0xfffffff0) != 0) {
-                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", class->name, packing_size);
+               if ((packing_size & 0xffffff00) != 0) {
+                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", class->name, packing_size);
                        mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, err_msg);
                        return;
                }
@@ -1580,7 +1597,7 @@ mono_class_setup_fields (MonoClass *class)
                return;
        }
 
-       if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+       if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT && !(mono_is_corlib_image (class->image) && !strcmp (class->name_space, "System") && !strcmp (class->name, "ValueType")))
                blittable = FALSE;
 
        /* Prevent infinite loops if the class references itself */
@@ -1748,12 +1765,27 @@ mono_class_has_references (MonoClass *klass)
 MonoType*
 mono_type_get_basic_type_from_generic (MonoType *type)
 {
-       /* When we do generic sharing we let type variables stand for reference types. */
-       if (!type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR))
+       /* When we do generic sharing we let type variables stand for reference/primitive types. */
+       if (!type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) &&
+               (!type->data.generic_param->gshared_constraint || type->data.generic_param->gshared_constraint->type == MONO_TYPE_OBJECT))
                return &mono_defaults.object_class->byval_arg;
        return type;
 }
 
+static gboolean
+type_has_references (MonoClass *klass, MonoType *ftype)
+{
+       if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (klass, ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype)))))
+               return TRUE;
+       if (!ftype->byref && (ftype->type == MONO_TYPE_VAR || ftype->type == MONO_TYPE_MVAR)) {
+               MonoGenericParam *gparam = ftype->data.generic_param;
+
+               if (gparam->gshared_constraint)
+                       return mono_class_has_references (mono_class_from_mono_type (gparam->gshared_constraint));
+       }
+       return FALSE;
+}
+
 /*
  * mono_class_layout_fields:
  * @class: a class
@@ -1814,7 +1846,7 @@ mono_class_layout_fields (MonoClass *class)
                if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
                        ftype = mono_type_get_underlying_type (field->type);
                        ftype = mono_type_get_basic_type_from_generic (ftype);
-                       if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype)))))
+                       if (type_has_references (class, ftype))
                                class->has_references = TRUE;
                }
        }
@@ -1827,7 +1859,7 @@ mono_class_layout_fields (MonoClass *class)
                if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
                        ftype = mono_type_get_underlying_type (field->type);
                        ftype = mono_type_get_basic_type_from_generic (ftype);
-                       if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype)))))
+                       if (type_has_references (class, ftype))
                                class->has_static_refs = TRUE;
                }
        }
@@ -1839,7 +1871,7 @@ mono_class_layout_fields (MonoClass *class)
 
                ftype = mono_type_get_underlying_type (field->type);
                ftype = mono_type_get_basic_type_from_generic (ftype);
-               if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype))))) {
+               if (type_has_references (class, ftype)) {
                        if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
                                class->has_static_refs = TRUE;
                        else
@@ -1890,7 +1922,7 @@ mono_class_layout_fields (MonoClass *class)
                                ftype = mono_type_get_underlying_type (field->type);
                                ftype = mono_type_get_basic_type_from_generic (ftype);
                                if (gc_aware_layout) {
-                                       if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype))))) {
+                                       if (type_has_references (class, ftype)) {
                                                if (pass == 1)
                                                        continue;
                                        } else {
@@ -1912,7 +1944,7 @@ mono_class_layout_fields (MonoClass *class)
                                /* if the field has managed references, we need to force-align it
                                 * see bug #77788
                                 */
-                               if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype)))))
+                               if (type_has_references (class, ftype))
                                        align = MAX (align, sizeof (gpointer));
 
                                class->min_align = MAX (align, class->min_align);
@@ -1967,7 +1999,7 @@ mono_class_layout_fields (MonoClass *class)
                        field->offset += sizeof (MonoObject);
                        ftype = mono_type_get_underlying_type (field->type);
                        ftype = mono_type_get_basic_type_from_generic (ftype);
-                       if (MONO_TYPE_IS_REFERENCE (ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype))))) {
+                       if (type_has_references (class, ftype)) {
                                if (field->offset % sizeof (gpointer)) {
                                        mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
                                }
@@ -2026,12 +2058,17 @@ mono_class_layout_fields (MonoClass *class)
 
        if (layout != TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) {
                /*
+                * This leads to all kinds of problems with nested structs, so only
+                * enable it when a MONO_DEBUG property is set.
+                *
                 * For small structs, set min_align to at least the struct size to improve
                 * performance, and since the JIT memset/memcpy code assumes this and generates 
                 * unaligned accesses otherwise. See #78990 for a testcase.
                 */
-               if (class->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
-                       class->min_align = MAX (class->min_align, class->instance_size - sizeof (MonoObject));
+               if (mono_align_small_structs) {
+                       if (class->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
+                               class->min_align = MAX (class->min_align, class->instance_size - sizeof (MonoObject));
+               }
        }
 
        mono_memory_barrier ();
@@ -2233,11 +2270,17 @@ mono_class_setup_methods (MonoClass *class)
                for (i = 0; i < class->interface_count; i++)
                        setup_generic_array_ifaces (class, class->interfaces [i], methods, first_generic + i * count_generic);
        } else {
+               MonoError error;
+
                count = class->method.count;
                methods = mono_class_alloc (class, sizeof (MonoMethod*) * count);
                for (i = 0; i < count; ++i) {
                        int idx = mono_metadata_translate_token_index (class->image, MONO_TABLE_METHOD, class->method.first + i + 1);
-                       methods [i] = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | idx, class);
+                       methods [i] = mono_get_method_checked (class->image, MONO_TOKEN_METHOD_DEF | idx, class, NULL, &error);
+                       if (!methods [i]) {
+                               mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Could not load method %d due to %s", i, mono_error_get_message (&error)));
+                               mono_error_cleanup (&error);
+                       }
                }
        }
 
@@ -2274,13 +2317,15 @@ mono_class_setup_methods (MonoClass *class)
 MonoMethod*
 mono_class_get_method_by_index (MonoClass *class, int index)
 {
+       MonoError error;
        /* Avoid calling setup_methods () if possible */
        if (class->generic_class && !class->methods) {
                MonoClass *gklass = class->generic_class->container_class;
                MonoMethod *m;
 
-               m = mono_class_inflate_generic_method_full (
-                               gklass->methods [index], class, mono_class_get_context (class));
+               m = mono_class_inflate_generic_method_full_checked (
+                               gklass->methods [index], class, mono_class_get_context (class), &error);
+               g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
                /*
                 * If setup_methods () is called later for this class, no duplicates are created,
                 * since inflate_generic_method guarantees that only one instance of a method
@@ -2319,10 +2364,14 @@ mono_class_get_inflated_method (MonoClass *class, MonoMethod *method)
 
        for (i = 0; i < gklass->method.count; ++i) {
                if (gklass->methods [i] == method) {
-                       if (class->methods)
+                       if (class->methods) {
                                return class->methods [i];
-                       else
-                               return mono_class_inflate_generic_method_full (gklass->methods [i], class, mono_class_get_context (class));
+                       } else {
+                               MonoError error;
+                               MonoMethod *result = mono_class_inflate_generic_method_full_checked (gklass->methods [i], class, mono_class_get_context (class), &error);
+                               g_assert (mono_error_ok (&error)); /* FIXME don't swallow this error */
+                               return result;
+                       }
                }
        }
 
@@ -2351,11 +2400,13 @@ mono_class_get_vtable_entry (MonoClass *class, int offset)
        }
 
        if (class->generic_class) {
+               MonoError error;
                MonoClass *gklass = class->generic_class->container_class;
                mono_class_setup_vtable (gklass);
                m = gklass->vtable [offset];
 
-               m = mono_class_inflate_generic_method_full (m, class, mono_class_get_context (class));
+               m = mono_class_inflate_generic_method_full_checked (m, class, mono_class_get_context (class), &error);
+               g_assert (mono_error_ok (&error)); /* FIXME don't swallow this error */
        } else {
                mono_class_setup_vtable (class);
                if (class->exception_type)
@@ -2412,17 +2463,19 @@ mono_class_setup_properties (MonoClass *class)
                properties = mono_class_new0 (class, MonoProperty, gklass->ext->property.count + 1);
 
                for (i = 0; i < gklass->ext->property.count; i++) {
+                       MonoError error;
                        MonoProperty *prop = &properties [i];
 
                        *prop = gklass->ext->properties [i];
 
                        if (prop->get)
-                               prop->get = mono_class_inflate_generic_method_full (
-                                       prop->get, class, mono_class_get_context (class));
+                               prop->get = mono_class_inflate_generic_method_full_checked (
+                                       prop->get, class, mono_class_get_context (class), &error);
                        if (prop->set)
-                               prop->set = mono_class_inflate_generic_method_full (
-                                       prop->set, class, mono_class_get_context (class));
+                               prop->set = mono_class_inflate_generic_method_full_checked (
+                                       prop->set, class, mono_class_get_context (class), &error);
 
+                       g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
                        prop->parent = class;
                }
 
@@ -2451,11 +2504,14 @@ mono_class_setup_properties (MonoClass *class)
 
                                mono_metadata_decode_row (msemt, j, cols, MONO_METHOD_SEMA_SIZE);
 
-                               if (class->image->uncompressed_metadata)
+                               if (class->image->uncompressed_metadata) {
+                                       MonoError error;
                                        /* It seems like the MONO_METHOD_SEMA_METHOD column needs no remapping */
-                                       method = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class);
-                               else
+                                       method = mono_get_method_checked (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class, NULL, &error);
+                                       mono_error_cleanup (&error); /* FIXME don't swallow this error */
+                               } else {
                                        method = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
+                               }
 
                                switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
                                case METHOD_SEMANTIC_SETTER:
@@ -2504,8 +2560,11 @@ inflate_method_listz (MonoMethod **methods, MonoClass *class, MonoGenericContext
 
        retval = g_new0 (MonoMethod*, count + 1);
        count = 0;
-       for (om = methods, count = 0; *om; ++om, ++count)
-               retval [count] = mono_class_inflate_generic_method_full (*om, class, context);
+       for (om = methods, count = 0; *om; ++om, ++count) {
+               MonoError error;
+               retval [count] = mono_class_inflate_generic_method_full_checked (*om, class, context, &error);
+               g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
+       }
 
        return retval;
 }
@@ -2543,14 +2602,21 @@ mono_class_setup_events (MonoClass *class)
                        context = mono_class_get_context (class);
 
                for (i = 0; i < count; i++) {
+                       MonoError error;
                        MonoEvent *event = &events [i];
                        MonoEvent *gevent = &gklass->ext->events [i];
 
+                       mono_error_init (&error); //since we do conditional calls, we must ensure the default value is ok
+
                        event->parent = class;
                        event->name = gevent->name;
-                       event->add = gevent->add ? mono_class_inflate_generic_method_full (gevent->add, class, context) : NULL;
-                       event->remove = gevent->remove ? mono_class_inflate_generic_method_full (gevent->remove, class, context) : NULL;
-                       event->raise = gevent->raise ? mono_class_inflate_generic_method_full (gevent->raise, class, context) : NULL;
+                       event->add = gevent->add ? mono_class_inflate_generic_method_full_checked (gevent->add, class, context, &error) : NULL;
+                       g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
+                       event->remove = gevent->remove ? mono_class_inflate_generic_method_full_checked (gevent->remove, class, context, &error) : NULL;
+                       g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
+                       event->raise = gevent->raise ? mono_class_inflate_generic_method_full_checked (gevent->raise, class, context, &error) : NULL;
+                       g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
+
 #ifndef MONO_SMALL_CONFIG
                        event->other = gevent->other ? inflate_method_listz (gevent->other, class, context) : NULL;
 #endif
@@ -2583,11 +2649,14 @@ mono_class_setup_events (MonoClass *class)
 
                                mono_metadata_decode_row (msemt, j, cols, MONO_METHOD_SEMA_SIZE);
 
-                               if (class->image->uncompressed_metadata)
+                               if (class->image->uncompressed_metadata) {
+                                       MonoError error;
                                        /* It seems like the MONO_METHOD_SEMA_METHOD column needs no remapping */
-                                       method = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class);
-                               else
+                                       method = mono_get_method_checked (class->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], class, NULL, &error);
+                                       mono_error_cleanup (&error); /* FIXME don't swallow this error */
+                               } else {
                                        method = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
+                               }
 
                                switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
                                case METHOD_SEMANTIC_ADD_ON:
@@ -3240,7 +3309,7 @@ static int
 find_interface_offset (int num_ifaces, MonoClass **interfaces_full, int *interface_offsets_full, MonoClass *ic)
 {
        int i = find_interface (num_ifaces, interfaces_full, ic);
-       if (ic >= 0)
+       if (i >= 0)
                return interface_offsets_full [i];
        return -1;
 }
@@ -3566,8 +3635,9 @@ setup_interface_offsets (MonoClass *class, int cur_slot, gboolean overwrite)
         * mono_class_setup_interface_offsets () passes 0 as CUR_SLOT, so the computed interface offsets will be invalid. This
         * means we have to overwrite those when called from other places (#4440).
         */
-       if (class->interfaces_packed && !overwrite) {
-               g_assert (class->interface_offsets_count == interface_offsets_count);
+       if (class->interfaces_packed) {
+               if (!overwrite)
+                       g_assert (class->interface_offsets_count == interface_offsets_count);
        } else {
                uint8_t *bitmap;
                int bsize;
@@ -3860,7 +3930,8 @@ is_wcf_hack_disabled (void)
 }
 
 static gboolean
-check_interface_method_override (MonoClass *class, MonoMethod *im, MonoMethod *cm, gboolean require_newslot, gboolean interface_is_explicitly_implemented_by_class, gboolean slot_is_empty, gboolean security_enabled) {
+check_interface_method_override (MonoClass *class, MonoMethod *im, MonoMethod *cm, gboolean require_newslot, gboolean interface_is_explicitly_implemented_by_class, gboolean slot_is_empty)
+{
        MonoMethodSignature *cmsig, *imsig;
        if (strcmp (im->name, cm->name) == 0) {
                if (! (cm->flags & METHOD_ATTRIBUTE_PUBLIC)) {
@@ -3895,11 +3966,6 @@ check_interface_method_override (MonoClass *class, MonoMethod *im, MonoMethod *c
                        return FALSE;
                }
                TRACE_INTERFACE_VTABLE (printf ("[SECURITY CHECKS]"));
-               /* CAS - SecurityAction.InheritanceDemand on interface */
-               if (security_enabled && (im->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
-                       mono_secman_inheritancedemand_method (cm, im);
-               }
-
                if (mono_security_core_clr_enabled ())
                        mono_security_core_clr_check_override (class, cm, im);
 
@@ -3981,11 +4047,6 @@ check_interface_method_override (MonoClass *class, MonoMethod *im, MonoMethod *c
                }
                
                TRACE_INTERFACE_VTABLE (printf ("[SECURITY CHECKS (INJECTED CASE)]"));
-               /* CAS - SecurityAction.InheritanceDemand on interface */
-               if (security_enabled && (im->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
-                       mono_secman_inheritancedemand_method (cm, im);
-               }
-
                if (mono_security_core_clr_enabled ())
                        mono_security_core_clr_check_override (class, cm, im);
 
@@ -4218,9 +4279,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
        int i, max_vtsize = 0, max_iid, cur_slot = 0;
        GPtrArray *ifaces = NULL;
        GHashTable *override_map = NULL;
-       gboolean security_enabled = mono_security_enabled ();
        MonoMethod *cm;
-       gpointer class_iter;
 #if (DEBUG_INTERFACE_VTABLE_CODE|TRACE_INTERFACE_VTABLE_CODE)
        int first_non_interface_slot;
 #endif
@@ -4457,15 +4516,13 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
                        // otherwise look for a matching method
                        if (override_im == NULL) {
                                int cm_index;
-                               gpointer iter;
                                MonoMethod *cm;
 
                                // First look for a suitable method among the class methods
-                               iter = NULL;
                                for (l = virt_methods; l; l = l->next) {
                                        cm = l->data;
                                        TRACE_INTERFACE_VTABLE (printf ("    For slot %d ('%s'.'%s':'%s'), trying method '%s'.'%s':'%s'... [EXPLICIT IMPLEMENTATION = %d][SLOT IS NULL = %d]", im_slot, ic->name_space, ic->name, im->name, cm->klass->name_space, cm->klass->name, cm->name, interface_is_explicitly_implemented_by_class, (vtable [im_slot] == NULL)));
-                                       if (check_interface_method_override (class, im, cm, TRUE, interface_is_explicitly_implemented_by_class, (vtable [im_slot] == NULL), security_enabled)) {
+                                       if (check_interface_method_override (class, im, cm, TRUE, interface_is_explicitly_implemented_by_class, (vtable [im_slot] == NULL))) {
                                                TRACE_INTERFACE_VTABLE (printf ("[check ok]: ASSIGNING"));
                                                vtable [im_slot] = cm;
                                                /* Why do we need this? */
@@ -4486,7 +4543,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
                                                MonoMethod *cm = parent->vtable [cm_index];
                                                
                                                TRACE_INTERFACE_VTABLE ((cm != NULL) && printf ("    For slot %d ('%s'.'%s':'%s'), trying (ancestor) method '%s'.'%s':'%s'... ", im_slot, ic->name_space, ic->name, im->name, cm->klass->name_space, cm->klass->name, cm->name));
-                                               if ((cm != NULL) && check_interface_method_override (class, im, cm, FALSE, FALSE, TRUE, security_enabled)) {
+                                               if ((cm != NULL) && check_interface_method_override (class, im, cm, FALSE, FALSE, TRUE)) {
                                                        TRACE_INTERFACE_VTABLE (printf ("[everything ok]: ASSIGNING"));
                                                        vtable [im_slot] = cm;
                                                        /* Why do we need this? */
@@ -4537,7 +4594,6 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
        }
 
        TRACE_INTERFACE_VTABLE (print_vtable_full (class, vtable, cur_slot, first_non_interface_slot, "AFTER SETTING UP INTERFACE METHODS", FALSE));
-       class_iter = NULL;
        for (l = virt_methods; l; l = l->next) {
                cm = l->data;
                /*
@@ -4565,11 +4621,6 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
                                        if (!strcmp(cm->name, m1->name) && 
                                            mono_metadata_signature_equal (cmsig, m1sig)) {
 
-                                               /* CAS - SecurityAction.InheritanceDemand */
-                                               if (security_enabled && (m1->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
-                                                       mono_secman_inheritancedemand_method (cm, m1);
-                                               }
-
                                                if (mono_security_core_clr_enabled ())
                                                        mono_security_core_clr_check_override (class, cm, m1);
 
@@ -4777,6 +4828,11 @@ mono_method_get_vtable_slot (MonoMethod *method)
                        MonoClass *gklass;
                        int i;
 
+                       if (!method->klass->generic_class) {
+                               g_assert (method->is_inflated);
+                               return mono_method_get_vtable_slot (((MonoMethodInflated*)method)->declaring);
+                       }
+
                        /* This can happen for abstract methods of generic instances due to the shortcut code in mono_class_setup_vtable_general (). */
                        g_assert (method->klass->generic_class);
                        gklass = method->klass->generic_class->container_class;
@@ -4924,10 +4980,12 @@ setup_generic_array_ifaces (MonoClass *class, MonoClass *iface, MonoMethod **met
        //g_print ("setting up array interface: %s\n", mono_type_get_name_full (&iface->byval_arg, 0));
 
        for (i = 0; i < generic_array_method_num; i++) {
+               MonoError error;
                MonoMethod *m = generic_array_method_info [i].array_method;
                MonoMethod *inflated;
 
-               inflated = mono_class_inflate_generic_method (m, &tmp_context);
+               inflated = mono_class_inflate_generic_method_checked (m, &tmp_context, &error);
+               g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
                methods [pos++] = mono_marshal_get_generic_array_helper (class, iface, generic_array_method_info [i].name, inflated);
        }
 }
@@ -5057,11 +5115,6 @@ mono_class_init (MonoClass *class)
                }
        }
 
-       /* CAS - SecurityAction.InheritanceDemand */
-       if (mono_security_enabled () && class->parent && (class->parent->flags & TYPE_ATTRIBUTE_HAS_SECURITY)) {
-               mono_secman_inheritancedemand_class (class, class->parent);
-       }
-
        mono_stats.initialized_class_count++;
 
        if (class->generic_class && !class->generic_class->is_dynamic) {
@@ -5805,8 +5858,9 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
 
        if (!class->enumtype) {
                if (!mono_metadata_interfaces_from_typedef_full (
-                           image, type_token, &interfaces, &icount, FALSE, context)){
-                       mono_class_set_failure_from_loader_error (class, error, g_strdup ("Could not load interfaces"));
+                           image, type_token, &interfaces, &icount, FALSE, context, error)){
+
+                       mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup (mono_error_get_message (error)));
                        mono_loader_unlock ();
                        mono_profiler_class_loaded (class, MONO_PROFILE_FAILED);
                        return NULL;
@@ -6002,7 +6056,13 @@ mono_generic_class_get_class (MonoGenericClass *gclass)
        mono_generic_class_setup_parent (klass, gklass);
 
        if (gclass->is_dynamic) {
-               klass->inited = 1;
+               /*
+                * We don't need to do any init workf with unbaked typebuilders. Generic instances created at this point will be later unregistered and/or fixed.
+                * This is to avoid work that would probably give wrong results as fields change as we build the TypeBuilder.
+                * See remove_instantiations_of_and_ensure_contents in reflection.c and its usage in reflection.c to understand the fixup stage of SRE banking.
+               */
+               if (!gklass->wastypebuilder)
+                       klass->inited = 1;
 
                mono_class_setup_supertypes (klass);
 
@@ -6106,9 +6166,14 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is
 
        /*Init these fields to sane values*/
        klass->min_align = 1;
-       klass->instance_size = sizeof (gpointer);
+       /*
+        * This makes sure the the value size of this class is equal to the size of the types the gparam is
+        * constrained to, the JIT depends on this.
+        */
+       klass->instance_size = sizeof (MonoObject) + mono_type_stack_size_internal (&klass->byval_arg, NULL, TRUE);
        mono_memory_barrier ();
        klass->size_inited = 1;
+       klass->setup_fields_called = 1;
 
        mono_class_setup_supertypes (klass);
 
@@ -6131,19 +6196,31 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is
 static MonoClass *
 get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, gboolean take_lock)
 {
-       int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
+       int n = mono_generic_param_num (param);
        MonoImage *image = param->image;
+       MonoClass *klass = NULL;
        GHashTable *ht;
 
        g_assert (image);
 
+       if (param->gshared_constraint) {
+               ht = is_mvar ? image->mvar_cache_constrained : image->var_cache_constrained;
+               if (ht) {
+                       if (take_lock)
+                               mono_image_lock (image);
+                       klass = g_hash_table_lookup (ht, param);
+                       if (take_lock)
+                               mono_image_unlock (image);
+               }
+               return klass;
+       }
+
        if (n < FAST_CACHE_SIZE) {
                if (is_mvar)
                        return image->mvar_cache_fast ? image->mvar_cache_fast [n] : NULL;
                else
                        return image->var_cache_fast ? image->var_cache_fast [n] : NULL;
        } else {
-               MonoClass *klass = NULL;
                ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
                if (ht) {
                        if (take_lock)
@@ -6162,12 +6239,23 @@ get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, gboolean take_
 static void
 set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass)
 {
-       int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
+       int n = mono_generic_param_num (param);
        MonoImage *image = param->image;
 
        g_assert (image);
 
-       if (n < FAST_CACHE_SIZE) {
+       if (param->gshared_constraint) {
+               GHashTable *ht = is_mvar ? image->mvar_cache_constrained : image->var_cache_constrained;
+               if (!ht) {
+                       ht = g_hash_table_new ((GHashFunc)mono_metadata_generic_param_hash, (GEqualFunc)mono_metadata_generic_param_equal);
+                       mono_memory_barrier ();
+                       if (is_mvar)
+                               image->mvar_cache_constrained = ht;
+                       else
+                               image->var_cache_constrained = ht;
+               }
+               g_hash_table_insert (ht, param, klass);
+       } else if (n < FAST_CACHE_SIZE) {
                if (is_mvar) {
                        /* Requires locking to avoid droping an already published class */
                        if (!image->mvar_cache_fast)
@@ -6639,6 +6727,8 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
 #endif
                class->cast_class = mono_defaults.int64_class;
                break;
+       default:
+               break;
        }
 
        class->element_class = eclass;
@@ -7221,10 +7311,7 @@ mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *c
        if (class && context && mono_metadata_token_table (type_token) == MONO_TABLE_TYPESPEC)
                class = mono_class_inflate_generic_class_checked (class, context, &error);
 
-       if (!class) {
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error); /*FIXME don't swallow this error */
-       }
+       g_assert (mono_error_ok (&error)); /* FIXME deprecate this function and forbit the runtime from using it. */
        return class;
 }
 
@@ -7623,21 +7710,8 @@ search_modules (MonoImage *image, const char *name_space, const char *name)
        return NULL;
 }
 
-/**
- * mono_class_from_name:
- * @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.
- *
- * To reference nested classes, use the "/" character as a separator.
- * For example use "Foo/Bar" to reference the class Bar that is nested
- * inside Foo, like this: "class Foo { class Bar {} }".
- */
 MonoClass *
-mono_class_from_name (MonoImage *image, const char* name_space, const char *name)
+mono_class_from_name_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error)
 {
        GHashTable *nspace_table;
        MonoImage *loaded_image;
@@ -7647,6 +7721,8 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name
        char *nested;
        char buf [1024];
 
+       mono_error_init (error);
+
        if ((nested = strchr (name, '/'))) {
                int pos = nested - name;
                int len = strlen (name);
@@ -7740,12 +7816,39 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name
 
        token = MONO_TOKEN_TYPE_DEF | token;
 
-       class = mono_class_get (image, token);
+       class = mono_class_get_checked (image, token, error);
        if (nested)
                return return_nested_in (class, nested);
        return class;
 }
 
+/**
+ * mono_class_from_name:
+ * @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.
+ *
+ * To reference nested classes, use the "/" character as a separator.
+ * For example use "Foo/Bar" to reference the class Bar that is nested
+ * inside Foo, like this: "class Foo { class Bar {} }".
+ */
+MonoClass *
+mono_class_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)) {
+               mono_loader_set_error_from_mono_error (&error);
+               mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+       }
+       return klass;
+}
+
 /**
  * mono_class_is_subclass_of:
  * @klass: class to probe if it is a subclass of another one
@@ -8290,8 +8393,13 @@ mono_class_get_cctor (MonoClass *klass)
        if (!klass->has_cctor)
                return NULL;
 
-       if (mono_class_get_cached_class_info (klass, &cached_info))
-               return mono_get_method (klass->image, cached_info.cctor_token, klass);
+       if (mono_class_get_cached_class_info (klass, &cached_info)) {
+               MonoError error;
+               MonoMethod *result = mono_get_method_checked (klass->image, cached_info.cctor_token, klass, NULL, &error);
+               if (!mono_error_ok (&error))
+                       g_error ("Could not lookup class cctor from cached metadata due to %s", mono_error_get_message (&error));
+               return result;
+       }
 
        if (klass->generic_class && !klass->methods)
                return mono_class_get_inflated_method (klass, mono_class_get_cctor (klass->generic_class->container_class));
@@ -8315,9 +8423,13 @@ mono_class_get_finalizer (MonoClass *klass)
        if (!mono_class_has_finalizer (klass))
                return NULL;
 
-       if (mono_class_get_cached_class_info (klass, &cached_info))
-               return mono_get_method (cached_info.finalize_image, cached_info.finalize_token, NULL);
-       else {
+       if (mono_class_get_cached_class_info (klass, &cached_info)) {
+               MonoError error;
+               MonoMethod *result = mono_get_method_checked (cached_info.finalize_image, cached_info.finalize_token, NULL, NULL, &error);
+               if (!mono_error_ok (&error))
+                       g_error ("Could not lookup finalizer from cached metadata due to %s", mono_error_get_message (&error));
+               return result;
+       }else {
                mono_class_setup_vtable (klass);
                return klass->vtable [finalize_slot];
        }
@@ -8377,8 +8489,6 @@ handle_enum:
        case MONO_TYPE_OBJECT:
        case MONO_TYPE_SZARRAY:
        case MONO_TYPE_ARRAY: 
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:   
                return sizeof (gpointer);
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
@@ -8394,7 +8504,12 @@ handle_enum:
        case MONO_TYPE_GENERICINST:
                type = &type->data.generic_class->container_class->byval_arg;
                goto handle_enum;
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR: {
+               int align;
 
+               return mono_type_size (type, &align);
+       }
        case MONO_TYPE_VOID:
                return 0;
                
@@ -8421,6 +8536,18 @@ gpointer
 mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class,
              MonoGenericContext *context)
 {
+       MonoError error;
+       gpointer res = mono_ldtoken_checked (image, token, handle_class, context, &error);
+       g_assert (mono_error_ok (&error));
+       return res;
+}
+
+gpointer
+mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **handle_class,
+             MonoGenericContext *context, MonoError *error)
+{
+       mono_error_init (error);
+
        if (image_is_dynamic (image)) {
                MonoClass *tmp_handle_class;
                gpointer obj = mono_lookup_dynamic_token_class (image, token, TRUE, &tmp_handle_class, context);
@@ -8439,43 +8566,42 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class,
        case MONO_TOKEN_TYPE_DEF:
        case MONO_TOKEN_TYPE_REF:
        case MONO_TOKEN_TYPE_SPEC: {
-               MonoError error;
                MonoType *type;
                if (handle_class)
                        *handle_class = mono_defaults.typehandle_class;
-               type = mono_type_get_checked (image, token, context, &error);
-               if (!type) {
-                       mono_loader_set_error_from_mono_error (&error);
-                       mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+               type = mono_type_get_checked (image, token, context, error);
+               if (!type)
                        return NULL;
-               }
+
                mono_class_init (mono_class_from_mono_type (type));
                /* We return a MonoType* as handle */
                return type;
        }
        case MONO_TOKEN_FIELD_DEF: {
                MonoClass *class;
-               MonoError error;
                guint32 type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token));
-               if (!type)
+               if (!type) {
+                       mono_error_set_bad_image (error, image, "Bad ldtoken %x", token);
                        return NULL;
+               }
                if (handle_class)
                        *handle_class = mono_defaults.fieldhandle_class;
-               class = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_DEF | type, context, &error);
-               if (!class) {
-                       mono_loader_set_error_from_mono_error (&error);
-                       mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+               class = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_DEF | type, context, error);
+               if (!class)
                        return NULL;
-               }
+
                mono_class_init (class);
                return mono_class_get_field (class, token);
        }
        case MONO_TOKEN_METHOD_DEF:
        case MONO_TOKEN_METHOD_SPEC: {
                MonoMethod *meth;
-               meth = mono_get_method_full (image, token, NULL, context);
+               meth = mono_get_method_checked (image, token, NULL, context, error);
                if (handle_class)
                        *handle_class = mono_defaults.methodhandle_class;
+               if (!meth)
+                       return NULL;
+
                return meth;
        }
        case MONO_TOKEN_MEMBER_REF: {
@@ -8485,28 +8611,22 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class,
                sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
                mono_metadata_decode_blob_size (sig, &sig);
                if (*sig == 0x6) { /* it's a field */
-                       MonoError error;
                        MonoClass *klass;
                        MonoClassField *field;
-                       field = mono_field_from_token_checked (image, token, &klass, context, &error);
+                       field = mono_field_from_token_checked (image, token, &klass, context, error);
                        if (handle_class)
                                *handle_class = mono_defaults.fieldhandle_class;
-                       if (!field) {
-                               mono_loader_set_error_from_mono_error (&error);
-                               mono_error_cleanup (&error); /* FIXME Don't swallow the error */
-                       }
                        return field;
                } else {
                        MonoMethod *meth;
-                       meth = mono_get_method_full (image, token, NULL, context);
+                       meth = mono_get_method_checked (image, token, NULL, context, error);
                        if (handle_class)
                                *handle_class = mono_defaults.methodhandle_class;
                        return meth;
                }
        }
        default:
-               g_warning ("Unknown token 0x%08x in ldtoken", token);
-               break;
+               mono_error_set_bad_image (error, image, "Bad ldtoken %x", token);
        }
        return NULL;
 }
@@ -8930,7 +9050,10 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                }
 
                if (i < klass->method.count) {
-                       res = mono_get_method (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass);
+                       MonoError error;
+                       res = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass, NULL, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+
                        /* Add 1 here so the if (*iter) check fails */
                        *iter = GUINT_TO_POINTER (i + 1);
                        return res;
@@ -9482,6 +9605,7 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in
 
        /* Search directly in the metadata to avoid calling setup_methods () */
        for (i = 0; i < klass->method.count; ++i) {
+               MonoError error;
                guint32 cols [MONO_METHOD_SIZE];
                MonoMethod *method;
                MonoMethodSignature *sig;
@@ -9490,13 +9614,21 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in
                mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, klass->method.first + i, cols, MONO_METHOD_SIZE);
 
                if (!strcmp (mono_metadata_string_heap (klass->image, cols [MONO_METHOD_NAME]), name)) {
-                       method = mono_get_method (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass);
+                       method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass, NULL, &error);
+                       if (!method) {
+                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                               continue;
+                       }
                        if (param_count == -1) {
                                res = method;
                                break;
                        }
-                       sig = mono_method_signature (method);
-                       if (sig && sig->param_count == param_count) {
+                       sig = mono_method_signature_checked (method, &error);
+                       if (!sig) {
+                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                               continue;
+                       }
+                       if (sig->param_count == param_count) {
                                res = method;
                                break;
                        }
@@ -9526,8 +9658,11 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p
 
        if (klass->generic_class && !klass->methods) {
                res = mono_class_get_method_from_name_flags (klass->generic_class->container_class, name, param_count, flags);
-               if (res)
-                       res = mono_class_inflate_generic_method_full (res, klass, mono_class_get_context (klass));
+               if (res) {
+                       MonoError error;
+                       res = mono_class_inflate_generic_method_full_checked (res, klass, mono_class_get_context (klass), &error);
+                       g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
+               }
                return res;
        }
 
@@ -9648,24 +9783,6 @@ mono_class_get_exception_for_failure (MonoClass *klass)
        gpointer exception_data = mono_class_get_exception_data (klass);
 
        switch (klass->exception_type) {
-#ifndef DISABLE_SECURITY
-       case MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND: {
-               MonoDomain *domain = mono_domain_get ();
-               MonoSecurityManager* secman = mono_security_manager_get_methods ();
-               MonoMethod *method = exception_data;
-               guint32 error = (method) ? MONO_METADATA_INHERITANCEDEMAND_METHOD : MONO_METADATA_INHERITANCEDEMAND_CLASS;
-               MonoObject *exc = NULL;
-               gpointer args [4];
-
-               args [0] = &error;
-               args [1] = mono_assembly_get_object (domain, mono_image_get_assembly (klass->image));
-               args [2] = mono_type_get_object (domain, &klass->byval_arg);
-               args [3] = (method) ? mono_method_get_object (domain, method, NULL) : NULL;
-
-               mono_runtime_invoke (secman->inheritsecurityexception, NULL, args, &exc);
-               return (MonoException*) exc;
-       }
-#endif
        case MONO_EXCEPTION_TYPE_LOAD: {
                MonoString *name;
                MonoException *ex;
@@ -9864,6 +9981,8 @@ can_access_instantiation (MonoClass *access_klass, MonoGenericInst *ginst)
                case MONO_TYPE_GENERICINST:
                        if (!can_access_type (access_klass, mono_class_from_mono_type (type)))
                                return FALSE;
+               default:
+                       break;
                }
        }
        return TRUE;
@@ -10161,8 +10280,9 @@ gboolean mono_type_is_valid_enum_basetype (MonoType * type) {
        case MONO_TYPE_I:
        case MONO_TYPE_U:
                return TRUE;
+       default:
+               return FALSE;
        }
-       return FALSE;
 }
 
 /**