Typo
[mono.git] / mono / metadata / icall.c
index 37dcfa503161b6c73a4b790ae911fd9c1f47643b..719e19ffbf3915122636657a8b141560bc7fa2d7 100644 (file)
@@ -67,6 +67,8 @@
 #include <mono/metadata/security-core-clr.h>
 #include <mono/metadata/mono-perfcounters.h>
 #include <mono/metadata/mono-debug.h>
+#include <mono/metadata/mono-ptr-array.h>
+#include <mono/metadata/verify-internals.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/strtod.h>
 #include <mono/utils/monobitset.h>
@@ -89,55 +91,19 @@ static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAs
 static MonoArray*
 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
 
-/* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
- * It works by allocating an initial small array on stack and only going to malloc'd memory if needed. 
- */
-typedef struct {
-       void **data;
-       int size;
-       int capacity;
-} MonoPtrArray;
-
-#define MONO_PTR_ARRAY_MAX_ON_STACK (16)
-
-#define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
-       (ARRAY).size = 0; \
-       (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
-       (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, NULL) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
-} while (0)
-
-#define mono_ptr_array_destroy(ARRAY) do {\
-       if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
-               mono_gc_free_fixed ((ARRAY).data); \
-} while (0)
-
-#define mono_ptr_array_append(ARRAY, VALUE) do { \
-       if ((ARRAY).size >= (ARRAY).capacity) {\
-               void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \
-               memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
-               if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK)     \
-                       mono_gc_free_fixed ((ARRAY).data);      \
-               (ARRAY).data = __tmp;                                                                                   \
-               (ARRAY).capacity *= 2;\
-       }\
-       ((ARRAY).data [(ARRAY).size++] = VALUE); \
-} while (0)
-
-#define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \
-       ((ARRAY).data [(IDX)] = VALUE); \
-} while (0)
-       
-#define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)])
-
-#define mono_ptr_array_size(ARRAY) ((ARRAY).size)
-
-
 static inline MonoBoolean
 is_generic_parameter (MonoType *type)
 {
        return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
 }
 
+static void
+mono_class_init_or_throw (MonoClass *klass)
+{
+       if (!mono_class_init (klass))
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+}
+
 /*
  * We expect a pointer to a char, not a string
  */
@@ -154,14 +120,10 @@ mono_double_ParseImpl (char *ptr, double *result)
                *result = strtod (ptr, &endptr);
 #else
        if (*ptr){
-#ifdef _EGLIB_MAJOR
-               /* Need to lock here because EGLIB (#464316) has locking defined as no-ops, and that breaks mono_strtod */
+               /* mono_strtod () is not thread-safe */
                EnterCriticalSection (&mono_strtod_mutex);
                *result = mono_strtod (ptr, &endptr);
                LeaveCriticalSection (&mono_strtod_mutex);
-#else
-               *result = mono_strtod (ptr, &endptr);
-#endif
        }
 #endif
 
@@ -557,7 +519,7 @@ ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
 static MonoArray *
 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
 {
-       MonoClass *aklass;
+       MonoClass *aklass, *klass;
        MonoArray *array;
        uintptr_t *sizes, i;
        gboolean bounded = FALSE;
@@ -575,13 +537,16 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *
                if (mono_array_get (lengths, gint32, i) < 0)
                        mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
 
+       klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+
        if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
                /* vectors are not the same as one dimensional arrays with no-zero bounds */
                bounded = TRUE;
        else
                bounded = FALSE;
 
-       aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
+       aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
 
        sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
        for (i = 0; i < aklass->rank; ++i) {
@@ -600,7 +565,7 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *
 static MonoArray *
 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
 {
-       MonoClass *aklass;
+       MonoClass *aklass, *klass;
        MonoArray *array;
        uintptr_t *sizes, i;
        gboolean bounded = FALSE;
@@ -619,13 +584,16 @@ ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray
                    (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX))
                        mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
 
+       klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+
        if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
                /* vectors are not the same as one dimensional arrays with no-zero bounds */
                bounded = TRUE;
        else
                bounded = FALSE;
 
-       aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
+       aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
 
        sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
        for (i = 0; i < aklass->rank; ++i) {
@@ -719,7 +687,6 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
        void * source_addr;
        MonoClass *src_class;
        MonoClass *dest_class;
-       int i;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -743,6 +710,10 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
 
        /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
        if (src_class == mono_defaults.object_class && dest_class->valuetype) {
+               // FIXME: This is racy
+               return FALSE;
+               /*
+                 int i;
                int has_refs = dest_class->has_references;
                for (i = source_idx; i < source_idx + length; ++i) {
                        MonoObject *elem = mono_array_get (source, MonoObject*, i);
@@ -763,6 +734,7 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
                                memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
                }
                return TRUE;
+               */
        }
 
        /* Check if we're copying a char[] <==> (u)short[] */
@@ -773,13 +745,18 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
                if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
                        ;
                /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
-               else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
+               else if (mono_class_is_subclass_of (dest_class, src_class, FALSE)) {
+                       // FIXME: This is racy
+                       return FALSE;
+                       /*
+                         int i;
                        for (i = source_idx; i < source_idx + length; ++i) {
                                MonoObject *elem = mono_array_get (source, MonoObject*, i);
                                if (elem && !mono_object_isinst (elem, dest_class))
                                        return FALSE;
                        }
-               else
+                       */
+               } else
                        return FALSE;
        }
 
@@ -857,12 +834,9 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoAr
        int align;
        const char *field_data;
 
-       if (MONO_TYPE_IS_REFERENCE (type) ||
-                       (type->type == MONO_TYPE_VALUETYPE &&
-                               (!mono_type_get_class (type) ||
-                               mono_type_get_class (type)->has_references))) {
+       if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
                MonoException *exc = mono_get_exception_argument("array",
-                       "Cannot initialize array containing references");
+                       "Cannot initialize array of non-primitive type.");
                mono_raise_exception (exc);
        }
 
@@ -1204,13 +1178,13 @@ mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
 }
 
 static gint32
-ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
+ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
 {
        MONO_ARCH_SAVE_REGS;
        
        MONO_CHECK_ARG_NULL (obj);
        
-       return mono_image_create_token (mb->dynamic_image, obj, TRUE, TRUE);
+       return mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE);
 }
 
 static gint32
@@ -1421,11 +1395,9 @@ static MonoReflectionType*
 ves_icall_type_from_handle (MonoType *handle)
 {
        MonoDomain *domain = mono_domain_get (); 
-       MonoClass *klass = mono_class_from_mono_type (handle);
 
        MONO_ARCH_SAVE_REGS;
 
-       mono_class_init (klass);
        return mono_type_get_object (domain, handle);
 }
 
@@ -1504,20 +1476,22 @@ handle_enum:
                return TYPECODE_SINGLE;
        case MONO_TYPE_R8:
                return TYPECODE_DOUBLE;
-       case MONO_TYPE_VALUETYPE:
-               if (type->type->data.klass->enumtype) {
-                       t = mono_class_enum_basetype (type->type->data.klass)->type;
+       case MONO_TYPE_VALUETYPE: {
+               MonoClass *klass = type->type->data.klass;
+               
+               if (klass->enumtype) {
+                       t = mono_class_enum_basetype (klass)->type;
                        goto handle_enum;
-               } else {
-                       MonoClass *k =  type->type->data.klass;
-                       if (strcmp (k->name_space, "System") == 0) {
-                               if (strcmp (k->name, "Decimal") == 0)
+               } else if (mono_is_corlib_image (klass->image)) {
+                       if (strcmp (klass->name_space, "System") == 0) {
+                               if (strcmp (klass->name, "Decimal") == 0)
                                        return TYPECODE_DECIMAL;
-                               else if (strcmp (k->name, "DateTime") == 0)
+                               else if (strcmp (klass->name, "DateTime") == 0)
                                        return TYPECODE_DATETIME;
                        }
                }
                return TYPECODE_OBJECT;
+       }
        case MONO_TYPE_STRING:
                return TYPECODE_STRING;
        case MONO_TYPE_SZARRAY:
@@ -1529,9 +1503,9 @@ handle_enum:
                return TYPECODE_OBJECT;
        case MONO_TYPE_CLASS:
                {
-                       MonoClass *k =  type->type->data.klass;
-                       if (strcmp (k->name_space, "System") == 0) {
-                               if (strcmp (k->name, "DBNull") == 0)
+                       MonoClass *klass =  type->type->data.klass;
+                       if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
+                               if (strcmp (klass->name, "DBNull") == 0)
                                        return TYPECODE_DBNULL;
                        }
                }
@@ -1563,6 +1537,19 @@ ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, M
        klass = mono_class_from_mono_type (type->type);
        klassc = mono_class_from_mono_type (c->type);
 
+       /* Interface check requires a more complex setup so we
+        * only do for them. Otherwise we simply avoid mono_class_init.
+        */
+       if (check_interfaces) {
+               mono_class_init_or_throw (klass);
+               mono_class_init_or_throw (klassc);
+       } else if (!klass->supertypes || !klassc->supertypes) {
+               mono_loader_lock ();
+               mono_class_setup_supertypes (klass);
+               mono_class_setup_supertypes (klassc);
+               mono_loader_unlock ();
+       }
+
        if (type->type->byref)
                return klassc == mono_defaults.object_class;
 
@@ -1602,6 +1589,9 @@ ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType
        klass = mono_class_from_mono_type (type->type);
        klassc = mono_class_from_mono_type (c->type);
 
+       mono_class_init_or_throw (klass);
+       mono_class_init_or_throw (klassc);
+
        if (type->type->byref ^ c->type->byref)
                return FALSE;
 
@@ -1634,6 +1624,7 @@ static guint32
 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
 {
        MonoClass *klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
        return mono_object_isinst (obj, klass) != NULL;
 }
 
@@ -1641,9 +1632,6 @@ static guint32
 ves_icall_get_attributes (MonoReflectionType *type)
 {
        MonoClass *klass = mono_class_from_mono_type (type->type);
-
-       MONO_ARCH_SAVE_REGS;
-
        return klass->flags;
 }
 
@@ -1705,23 +1693,32 @@ ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
 static MonoArray*
 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
 {
-       MonoType *type = field->field->type;
+       MonoError error;
+       MonoType *type = mono_field_get_type_checked (field->field, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
 
        return type_array_from_modifiers (field->field->parent->image, type, optional);
 }
 
+static int
+vell_icall_get_method_attributes (MonoMethod *method)
+{
+       return method->flags;
+}
+
 static void
 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
 {
+       MonoError error;
        MonoDomain *domain = mono_domain_get ();
        MonoMethodSignature* sig;
        MONO_ARCH_SAVE_REGS;
 
-       sig = mono_method_signature (method);
-       if (!sig) {
-               g_assert (mono_loader_get_last_error ());
-               mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
-       }
+       sig = mono_method_signature_checked (method, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
+
 
        MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &method->klass->byval_arg));
        MONO_STRUCT_SETREF (info, ret, mono_type_get_object (domain, sig->ret));
@@ -1771,6 +1768,10 @@ ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
 static gint32
 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
 {
+       MonoClass *parent = field->field->parent;
+       if (!parent->size_inited)
+               mono_class_init (parent);
+
        return field->field->offset - sizeof (MonoObject);
 }
 
@@ -1805,7 +1806,9 @@ ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *ob
 static void
 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
 {
+       MonoError error;
        MonoClassField *cf = field->field;
+       MonoType *type;
        gchar *v;
 
        MONO_ARCH_SAVE_REGS;
@@ -1817,9 +1820,13 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
        if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
                mono_security_core_clr_ensure_reflection_access_field (cf);
 
+       type = mono_field_get_type_checked (cf, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
+
        v = (gchar *) value;
-       if (!cf->type->byref) {
-               switch (cf->type->type) {
+       if (!type->byref) {
+               switch (type->type) {
                case MONO_TYPE_U1:
                case MONO_TYPE_I1:
                case MONO_TYPE_BOOLEAN:
@@ -1835,6 +1842,7 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
                case MONO_TYPE_I8:
                case MONO_TYPE_R8:
                case MONO_TYPE_VALUETYPE:
+               case MONO_TYPE_PTR:
                        if (v != NULL)
                                v += sizeof (MonoObject);
                        break;
@@ -1846,11 +1854,11 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
                        /* Do nothing */
                        break;
                case MONO_TYPE_GENERICINST: {
-                       MonoGenericClass *gclass = cf->type->data.generic_class;
+                       MonoGenericClass *gclass = type->data.generic_class;
                        g_assert (!gclass->context.class_inst->is_open);
 
-                       if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
-                               MonoClass *nklass = mono_class_from_mono_type (cf->type);
+                       if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
+                               MonoClass *nklass = mono_class_from_mono_type (type);
                                MonoObject *nullable;
 
                                /* 
@@ -1871,12 +1879,12 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
                }
                default:
                        g_error ("type 0x%x not handled in "
-                                "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
+                                "ves_icall_FieldInfo_SetValueInternal", type->type);
                        return;
                }
        }
 
-       if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+       if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
                MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, TRUE);
                if (!vtable->initialized)
                        mono_runtime_class_init (vtable);
@@ -1950,6 +1958,17 @@ ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
        return o;
 }
 
+static MonoReflectionType*
+ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
+{
+       MonoError error;
+       MonoClassField *field = ref_field->field;
+       MonoType *type = mono_field_get_type_checked (field, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
+       return mono_type_get_object (mono_object_domain (ref_field), type);
+}
+
 static MonoReflectionType*
 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
 {
@@ -1977,8 +1996,8 @@ ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo
 
        if ((req_info & PInfo_ReflectedType) != 0)
                MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
-       else if ((req_info & PInfo_DeclaringType) != 0)
-               MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
+       if ((req_info & PInfo_DeclaringType) != 0)
+               MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &property->property->parent->byval_arg));
 
        if ((req_info & PInfo_Name) != 0)
                MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
@@ -2028,70 +2047,104 @@ ves_icall_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
 #endif
 }
 
+static void
+collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
+{
+       int i;
+       MonoClass *ic;
+
+       mono_class_setup_interfaces (klass, error);
+       if (!mono_error_ok (error))
+               return;
+
+       for (i = 0; i < klass->interface_count; i++) {
+               ic = klass->interfaces [i];
+               g_hash_table_insert (ifaces, ic, ic);
+
+               collect_interfaces (ic, ifaces, error);
+               if (!mono_error_ok (error))
+                       return;
+       }
+}
+
+typedef struct {
+       MonoArray *iface_array;
+       MonoGenericContext *context;
+       MonoError *error;
+       MonoDomain *domain;
+       int next_idx;
+} FillIfaceArrayData;
+
+static void
+fill_iface_array (gpointer key, gpointer value, gpointer user_data)
+{
+       FillIfaceArrayData *data = user_data;
+       MonoClass *ic = key;
+       MonoType *ret = &ic->byval_arg, *inflated = NULL;
+
+       if (!mono_error_ok (data->error))
+               return;
+
+       if (data->context && ic->generic_class && ic->generic_class->context.class_inst->is_open) {
+               inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
+               if (!mono_error_ok (data->error))
+                       return;
+       }
+
+       mono_array_setref (data->iface_array, data->next_idx++, mono_type_get_object (data->domain, ret));
+
+       if (inflated)
+               mono_metadata_free_type (inflated);
+}
+
 static MonoArray*
 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
 {
        MonoError error;
-       MonoDomain *domain = mono_object_domain (type); 
-       MonoArray *intf;
-       GPtrArray *ifaces = NULL;
-       int i;
        MonoClass *class = mono_class_from_mono_type (type->type);
        MonoClass *parent;
-       MonoBitSet *slots;
-       MonoGenericContext *context = NULL;
+       FillIfaceArrayData data = { 0 };
+       int len;
 
-       MONO_ARCH_SAVE_REGS;
+       GHashTable *iface_hash = g_hash_table_new (NULL, NULL);
 
        if (class->generic_class && class->generic_class->context.class_inst->is_open) {
-               context = mono_class_get_context (class);
+               data.context = mono_class_get_context (class);
                class = class->generic_class->container_class;
        }
 
-       mono_class_setup_vtable (class);
-
-       slots = mono_bitset_new (class->max_interface_id + 1, 0);
-
        for (parent = class; parent; parent = parent->parent) {
-               GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent, &error);
-               if (!mono_error_ok (&error)) {
-                       mono_bitset_free (slots);
-                       mono_error_raise_exception (&error);
-                       return NULL;
-               } else if (tmp_ifaces) {
-                       for (i = 0; i < tmp_ifaces->len; ++i) {
-                               MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
+               mono_class_setup_interfaces (parent, &error);
+               if (!mono_error_ok (&error))
+                       goto fail;
+               collect_interfaces (parent, iface_hash, &error);
+               if (!mono_error_ok (&error))
+                       goto fail;
+       }
 
-                               if (mono_bitset_test (slots, ic->interface_id))
-                                       continue;
+       data.error = &error;
+       data.domain = mono_object_domain (type);
 
-                               mono_bitset_set (slots, ic->interface_id);
-                               if (ifaces == NULL)
-                                       ifaces = g_ptr_array_new ();
-                               g_ptr_array_add (ifaces, ic);
-                       }
-                       g_ptr_array_free (tmp_ifaces, TRUE);
-               }
+       len = g_hash_table_size (iface_hash);
+       if (len == 0) {
+               g_hash_table_destroy (iface_hash);
+               if (!data.domain->empty_types)
+                       data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.monotype_class, 0);
+               return data.domain->empty_types;
        }
-       mono_bitset_free (slots);
 
-       if (!ifaces)
-               return mono_array_new_cached (domain, mono_defaults.monotype_class, 0);
-               
-       intf = mono_array_new_cached (domain, mono_defaults.monotype_class, ifaces->len);
-       for (i = 0; i < ifaces->len; ++i) {
-               MonoClass *ic = g_ptr_array_index (ifaces, i);
-               MonoType *ret = &ic->byval_arg, *inflated = NULL;
-               if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
-                       inflated = ret = mono_class_inflate_generic_type (ret, context);
-               
-               mono_array_setref (intf, i, mono_type_get_object (domain, ret));
-               if (inflated)
-                       mono_metadata_free_type (inflated);
-       }
-       g_ptr_array_free (ifaces, TRUE);
+       data.iface_array = mono_array_new_cached (data.domain, mono_defaults.monotype_class, len);
+       g_hash_table_foreach (iface_hash, fill_iface_array, &data);
+       if (!mono_error_ok (&error))
+               goto fail;
+
+       g_hash_table_destroy (iface_hash);
+       return data.iface_array;
 
-       return intf;
+fail:
+       g_hash_table_destroy (iface_hash);
+       mono_error_raise_exception (&error);
+       return NULL;
 }
 
 static void
@@ -2107,6 +2160,8 @@ ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType
        MonoDomain *domain;
 
        MONO_ARCH_SAVE_REGS;
+       mono_class_init_or_throw (class);
+       mono_class_init_or_throw (iclass);
 
        mono_class_setup_vtable (class);
 
@@ -2133,6 +2188,7 @@ static void
 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
 {
        MonoClass *klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
 
        if (klass->image->dynamic) {
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
@@ -2154,6 +2210,7 @@ ves_icall_MonoType_GetElementType (MonoReflectionType *type)
                return mono_type_get_object (mono_object_domain (type), &type->type->data.klass->byval_arg);
 
        class = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (class);
 
        // GetElementType should only return a type for:
        // Array Pointer PassedByRef
@@ -2171,9 +2228,6 @@ static MonoReflectionType*
 ves_icall_get_type_parent (MonoReflectionType *type)
 {
        MonoClass *class = mono_class_from_mono_type (type->type);
-
-       MONO_ARCH_SAVE_REGS;
-
        return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
 }
 
@@ -2205,7 +2259,7 @@ static MonoBoolean
 ves_icall_type_iscomobject (MonoReflectionType *type)
 {
        MonoClass *klass = mono_class_from_mono_type (type->type);
-       MONO_ARCH_SAVE_REGS;
+       mono_class_init_or_throw (klass);
 
        return (klass && klass->is_com_object);
 }
@@ -2214,9 +2268,6 @@ static MonoReflectionModule*
 ves_icall_MonoType_get_Module (MonoReflectionType *type)
 {
        MonoClass *class = mono_class_from_mono_type (type->type);
-
-       MONO_ARCH_SAVE_REGS;
-
        return mono_module_get_object (mono_object_domain (type), class->image);
 }
 
@@ -2225,9 +2276,6 @@ ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
 {
        MonoDomain *domain = mono_domain_get (); 
        MonoClass *class = mono_class_from_mono_type (type->type);
-
-       MONO_ARCH_SAVE_REGS;
-
        return mono_assembly_get_object (domain, class->image->assembly);
 }
 
@@ -2251,30 +2299,12 @@ ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
        return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
 }
 
-static MonoReflectionType*
-ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
-{
-       MonoDomain *domain = mono_domain_get (); 
-       MonoClass *class = mono_class_from_mono_type (type->type);
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (class->enumtype && mono_class_enum_basetype (class)) /* types that are modified typebuilders may not have enum_basetype set */
-               return mono_type_get_object (domain, mono_class_enum_basetype (class));
-       else if (class->element_class)
-               return mono_type_get_object (domain, &class->element_class->byval_arg);
-       else
-               return NULL;
-}
-
 static MonoString*
 ves_icall_MonoType_get_Name (MonoReflectionType *type)
 {
        MonoDomain *domain = mono_domain_get (); 
        MonoClass *class = mono_class_from_mono_type (type->type);
 
-       MONO_ARCH_SAVE_REGS;
-
        if (type->type->byref) {
                char *n = g_strdup_printf ("%s&", class->name);
                MonoString *res = mono_string_new (domain, n);
@@ -2293,8 +2323,6 @@ ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
        MonoDomain *domain = mono_domain_get (); 
        MonoClass *class = mono_class_from_mono_type (type->type);
 
-       MONO_ARCH_SAVE_REGS;
-
        while (class->nested_in)
                class = class->nested_in;
 
@@ -2313,6 +2341,7 @@ ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
                mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type"));
 
        class = mono_class_from_mono_type (type->type);
+
        return class->rank;
 }
 
@@ -2359,7 +2388,6 @@ ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
                return FALSE;
 
        klass = mono_class_from_mono_type (type->type);
-
        return klass->generic_container != NULL;
 }
 
@@ -2373,6 +2401,7 @@ ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
                return NULL;
 
        klass = mono_class_from_mono_type (type->type);
+
        if (klass->generic_container) {
                return type; /* check this one */
        }
@@ -2393,10 +2422,12 @@ ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
 static MonoReflectionType*
 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
 {
+       MonoClass *class;
        MonoType *geninst, **types;
        int i, count;
 
-       MONO_ARCH_SAVE_REGS;
+       g_assert (IS_MONOTYPE (type));
+       mono_class_init_or_throw (mono_class_from_mono_type (type->type));
 
        count = mono_array_length (type_array);
        types = g_new0 (MonoType *, count);
@@ -2411,6 +2442,12 @@ ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
        if (!geninst)
                return NULL;
 
+       class = mono_class_from_mono_type (geninst);
+
+       /*we might inflate to the GTD*/
+       if (class->generic_class && !mono_verifier_class_is_valid_generic_instantiation (class))
+               mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
+
        return mono_type_get_object (mono_object_domain (type), geninst);
 }
 
@@ -2424,6 +2461,7 @@ ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
                return FALSE;
 
        klass = mono_class_from_mono_type (type->type);
+
        return klass->generic_class != NULL;
 }
 
@@ -2527,6 +2565,7 @@ ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
        domain = ((MonoObject *)type)->vtable->domain;
 
        klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
 
        iter = NULL;
        while ((method = mono_class_get_methods (klass, &iter))) {
@@ -3014,6 +3053,9 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
 
        domain = mono_object_domain (enumType); 
        enumc = mono_class_from_mono_type (enumType->type);
+
+       mono_class_init_or_throw (enumc);
+
        objc = value->vtable->klass;
 
        if (!enumc->enumtype)
@@ -3064,10 +3106,14 @@ static MonoReflectionType *
 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
 {
        MonoType *etype;
+       MonoClass *klass;
 
        MONO_ARCH_SAVE_REGS;
 
-       etype = mono_class_enum_basetype (mono_class_from_mono_type (type->type));
+       klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+
+       etype = mono_class_enum_basetype (klass);
        if (!etype)
                /* MS throws this for typebuilders */
                mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
@@ -3169,6 +3215,8 @@ ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
 
        MONO_ARCH_SAVE_REGS;
 
+       mono_class_init_or_throw (enumc);
+
        MONO_STRUCT_SETREF (info, utype, mono_type_get_object (domain, mono_class_enum_basetype (enumc)));
        nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
        MONO_STRUCT_SETREF (info, names, mono_array_new (domain, mono_defaults.string_class, nvalues));
@@ -3181,6 +3229,8 @@ ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
                int len;
                MonoTypeEnum def_type;
                
+               if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
+                       continue;
                if (strcmp ("value__", mono_field_get_name (field)) == 0)
                        continue;
                if (mono_field_is_deleted (field))
@@ -3246,8 +3296,6 @@ ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bfl
        domain = ((MonoObject *)type)->vtable->domain;
        klass = startklass = mono_class_from_mono_type (type->type);
 
-       MONO_ARCH_SAVE_REGS;
-
        if (!name)
                mono_raise_exception (mono_get_exception_argument_null ("name"));
        if (type->type->byref)
@@ -3260,17 +3308,16 @@ handle_parent:
                mono_raise_exception (mono_class_get_exception_for_failure (klass));
 
        iter = NULL;
-       while ((field = mono_class_get_fields (klass, &iter))) {
+       while ((field = mono_class_get_fields_lazy (klass, &iter))) {
+               guint32 flags = mono_field_get_flags (field);
                match = 0;
 
-               if (field->type == NULL)
-                       continue;
-               if (mono_field_is_deleted (field))
+               if (mono_field_is_deleted_with_flags (field, flags))
                        continue;
-               if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
+               if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
                        if (bflags & BFLAGS_Public)
                                match++;
-               } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
+               } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
                        if (bflags & BFLAGS_NonPublic) {
                                match++;
                        }
@@ -3278,7 +3325,7 @@ handle_parent:
                if (!match)
                        continue;
                match = 0;
-               if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+               if (flags & FIELD_ATTRIBUTE_STATIC) {
                        if (bflags & BFLAGS_Static)
                                if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
                                        match++;
@@ -3329,18 +3376,21 @@ ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, Mon
        mono_ptr_array_init (tmp_array, 2);
        
 handle_parent: 
-       if (klass->exception_type != MONO_EXCEPTION_NONE)
+       if (klass->exception_type != MONO_EXCEPTION_NONE) {
+               mono_ptr_array_destroy (tmp_array);
                mono_raise_exception (mono_class_get_exception_for_failure (klass));
+       }
 
        iter = NULL;
-       while ((field = mono_class_get_fields (klass, &iter))) {
+       while ((field = mono_class_get_fields_lazy (klass, &iter))) {
+               guint32 flags = mono_field_get_flags (field);
                match = 0;
-               if (mono_field_is_deleted (field))
+               if (mono_field_is_deleted_with_flags (field, flags))
                        continue;
-               if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
+               if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
                        if (bflags & BFLAGS_Public)
                                match++;
-               } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
+               } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
                        if (bflags & BFLAGS_NonPublic) {
                                match++;
                        }
@@ -3348,7 +3398,7 @@ handle_parent:
                if (!match)
                        continue;
                match = 0;
-               if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+               if (flags & FIELD_ATTRIBUTE_STATIC) {
                        if (bflags & BFLAGS_Static)
                                if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
                                        match++;
@@ -3410,8 +3460,6 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        MonoException *ex;
        MonoPtrArray tmp_array;
 
-       MONO_ARCH_SAVE_REGS;
-
        mono_ptr_array_init (tmp_array, 4);
 
        if (!MethodInfo_array) {
@@ -3426,6 +3474,7 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
                return mono_array_new_specific (array_vtable, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
        refklass = mono_class_from_mono_type (reftype->type);
+
        len = 0;
        if (name != NULL) {
                mname = mono_string_to_utf8 (name);
@@ -3563,9 +3612,6 @@ ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflag
        klass = startklass = mono_class_from_mono_type (type->type);
        refklass = mono_class_from_mono_type (reftype->type);
 
-       if (klass->exception_type != MONO_EXCEPTION_NONE)
-               mono_raise_exception (mono_class_get_exception_for_failure (klass));
-
        if (!System_Reflection_ConstructorInfo)
                System_Reflection_ConstructorInfo = mono_class_from_name (
                        mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
@@ -3645,6 +3691,7 @@ property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
 static MonoArray*
 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
 {
+       MonoException *ex;
        MonoDomain *domain; 
        static MonoClass *System_Reflection_PropertyInfo;
        MonoClass *startklass, *klass;
@@ -3656,7 +3703,7 @@ ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name,
        gchar *propname = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        gpointer iter;
-       GHashTable *properties;
+       GHashTable *properties = NULL;
        MonoPtrArray tmp_array;
 
        MONO_ARCH_SAVE_REGS;
@@ -3671,22 +3718,17 @@ ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name,
        if (type->type->byref)
                return mono_array_new_cached (domain, System_Reflection_PropertyInfo, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
+
        if (name != NULL) {
                propname = mono_string_to_utf8 (name);
                compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
        }
 
-       mono_class_setup_vtable (klass);
-
        properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
 handle_parent:
        mono_class_setup_vtable (klass);
-       if (klass->exception_type != MONO_EXCEPTION_NONE) {
-               g_hash_table_destroy (properties);
-               if (name != NULL)
-                       g_free (propname);
-               mono_raise_exception (mono_class_get_exception_for_failure (klass));
-       }
+       if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+               goto loader_error;
 
        iter = NULL;
        while ((prop = mono_class_get_properties (klass, &iter))) {
@@ -3749,6 +3791,22 @@ handle_parent:
        mono_ptr_array_destroy (tmp_array);
 
        return res;
+
+loader_error:
+       if (properties)
+               g_hash_table_destroy (properties);
+       if (name)
+               g_free (propname);
+       mono_ptr_array_destroy (tmp_array);
+
+       if (klass->exception_type != MONO_EXCEPTION_NONE) {
+               ex = mono_class_get_exception_for_failure (klass);
+       } else {
+               ex = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+               mono_loader_clear_error ();
+       }
+       mono_raise_exception (ex);
+       return NULL;
 }
 
 static MonoReflectionEvent *
@@ -3760,6 +3818,7 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32
        MonoEvent *event;
        MonoMethod *method;
        gchar *event_name;
+       int (*compare_func) (const char *s1, const char *s2);
 
        MONO_ARCH_SAVE_REGS;
 
@@ -3769,13 +3828,16 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32
        klass = startklass = mono_class_from_mono_type (type->type);
        domain = mono_object_domain (type);
 
+       mono_class_init_or_throw (klass);
+
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
 handle_parent: 
        if (klass->exception_type != MONO_EXCEPTION_NONE)
                mono_raise_exception (mono_class_get_exception_for_failure (klass));
 
        iter = NULL;
        while ((event = mono_class_get_events (klass, &iter))) {
-               if (strcmp (event->name, event_name))
+               if (compare_func (event->name, event_name))
                        continue;
 
                method = event->add;
@@ -3821,6 +3883,7 @@ handle_parent:
 static MonoArray*
 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
 {
+       MonoException *ex;
        MonoDomain *domain; 
        static MonoClass *System_Reflection_EventInfo;
        MonoClass *startklass, *klass;
@@ -3845,9 +3908,10 @@ ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, Mon
                return mono_array_new_cached (domain, System_Reflection_EventInfo, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
 
-handle_parent: 
-       if (klass->exception_type != MONO_EXCEPTION_NONE)
-               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+handle_parent:
+       mono_class_setup_vtable (klass);
+       if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+               goto loader_error;
 
        iter = NULL;
        while ((event = mono_class_get_events (klass, &iter))) {
@@ -3900,6 +3964,17 @@ handle_parent:
        mono_ptr_array_destroy (tmp_array);
 
        return res;
+
+loader_error:
+       mono_ptr_array_destroy (tmp_array);
+       if (klass->exception_type != MONO_EXCEPTION_NONE) {
+               ex = mono_class_get_exception_for_failure (klass);
+       } else {
+               ex = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+               mono_loader_clear_error ();
+       }
+       mono_raise_exception (ex);
+       return NULL;
 }
 
 static MonoReflectionType *
@@ -3920,6 +3995,7 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3
        if (type->type->byref)
                return NULL;
        klass = mono_class_from_mono_type (type->type);
+
        str = mono_string_to_utf8 (name);
 
  handle_parent:
@@ -3979,8 +4055,6 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
        if (type->type->byref)
                return mono_array_new (domain, mono_defaults.monotype_class, 0);
        klass = mono_class_from_mono_type (type->type);
-       if (klass->exception_type != MONO_EXCEPTION_NONE)
-               mono_raise_exception (mono_class_get_exception_for_failure (klass));
 
        /*
         * If a nested type is generic, return its generic type definition.
@@ -4107,6 +4181,10 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                        mono_raise_exception (e);
 
                return NULL;
+       } else if (mono_loader_get_last_error ()) {
+               if (throwOnError)
+                       mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+               mono_loader_clear_error ();
        }
 
        if (type->type == MONO_TYPE_CLASS) {
@@ -4823,7 +4901,6 @@ ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full
        MonoString *res;
        gchar *name;
 
-       MONO_ARCH_SAVE_REGS;
        if (full_name)
                format = assembly_qualified ?
                        MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
@@ -4850,6 +4927,7 @@ static int
 vell_icall_MonoType_get_core_clr_security_level (MonoReflectionType *this)
 {
        MonoClass *klass = mono_class_from_mono_type (this->type);
+       mono_class_init_or_throw (klass);
        return mono_security_core_clr_class_level (klass);
 }
 
@@ -4873,6 +4951,7 @@ fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *a
        aname->revision = name->revision;
        aname->hashalg = name->hash_alg;
        aname->versioncompat = 1; /* SameMachine (default) */
+       aname->processor_architecture = name->arch;
 
        if (by_default_version)
                MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
@@ -4959,14 +5038,7 @@ ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assem
        MonoString *res;
        gchar *name;
 
-       name = g_strdup_printf (
-               "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
-               mass->aname.name,
-               mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
-               mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
-               mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
-               (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
-
+       name = mono_stringify_assembly_name (&mass->aname);
        res = mono_string_new (domain, name);
        g_free (name);
 
@@ -5344,14 +5416,23 @@ ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *modul
 }
 
 static gboolean
-mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
-{
-       guint32 cols [MONO_MEMBERREF_SIZE];
-       const char *sig;
-       mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
-       sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
-       mono_metadata_decode_blob_size (sig, &sig);
-       return (*sig != 0x6);
+mono_memberref_is_method (MonoImage *image, guint32 token)
+{
+       if (!image->dynamic) {
+               guint32 cols [MONO_MEMBERREF_SIZE];
+               const char *sig;
+               mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
+               sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
+               mono_metadata_decode_blob_size (sig, &sig);
+               return (*sig != 0x6);
+       } else {
+               MonoClass *handle_class;
+
+               if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL))
+                       return FALSE;
+
+               return mono_defaults.methodhandle_class == handle_class;
+       }
 }
 
 static void
@@ -5387,12 +5468,14 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t
        }
 
        if (image->dynamic) {
-               if (type_args || method_args)
-                       mono_raise_exception (mono_get_exception_not_implemented (NULL));
-               klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
-               if (!klass)
-                       return NULL;
-               return &klass->byval_arg;
+               if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
+                       klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+                       return klass ? &klass->byval_arg : NULL;
+               }
+
+               init_generic_context_from_args (&context, type_args, method_args);
+               klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
+               return klass ? &klass->byval_arg : NULL;
        }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
@@ -5430,17 +5513,23 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
        }
 
        if (image->dynamic) {
-               if (type_args || method_args)
-                       mono_raise_exception (mono_get_exception_not_implemented (NULL));
-               /* FIXME: validate memberref token type */
-               return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+               if (table == MONO_TABLE_METHOD)
+                       return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+
+               if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
+                       *error = ResolveTokenError_BadTable;
+                       return NULL;
+               }
+
+               init_generic_context_from_args (&context, type_args, method_args);
+               return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
        }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
                *error = ResolveTokenError_OutOfRange;
                return NULL;
        }
-       if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
+       if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
                *error = ResolveTokenError_BadTable;
                return NULL;
        }
@@ -5498,17 +5587,23 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32
        }
 
        if (image->dynamic) {
-               if (type_args || method_args)
-                       mono_raise_exception (mono_get_exception_not_implemented (NULL));
-               /* FIXME: validate memberref token type */
-               return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+               if (table == MONO_TABLE_FIELD)
+                       return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+
+               if (mono_memberref_is_method (image, token)) {
+                       *error = ResolveTokenError_BadTable;
+                       return NULL;
+               }
+
+               init_generic_context_from_args (&context, type_args, method_args);
+               return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
        }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
                *error = ResolveTokenError_OutOfRange;
                return NULL;
        }
-       if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
+       if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
                *error = ResolveTokenError_BadTable;
                return NULL;
        }
@@ -5556,7 +5651,7 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32
                        return NULL;
        }
        case MONO_TABLE_MEMBERREF:
-               if (mono_metadata_memberref_is_method (image, token)) {
+               if (mono_memberref_is_method (image, token)) {
                        MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
                        if (m)
                                return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
@@ -5685,6 +5780,20 @@ ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
        return res;
 }
 
+static void
+check_for_invalid_type (MonoClass *klass)
+{
+       char *name;
+       MonoString *str;
+       if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
+               return;
+
+       name = mono_type_get_full_name (klass);
+       str =  mono_string_new (mono_domain_get (), name);
+       g_free (name);
+       mono_raise_exception ((MonoException*)mono_get_exception_type_load (str, NULL));
+
+}
 static MonoReflectionType *
 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
 {
@@ -5693,6 +5802,8 @@ ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
        MONO_ARCH_SAVE_REGS;
 
        klass = mono_class_from_mono_type (type->type);
+       check_for_invalid_type (klass);
+
        if (rank == 0) //single dimentional array
                aklass = mono_array_class_get (klass, 1);
        else
@@ -5709,6 +5820,8 @@ ves_icall_Type_make_byref_type (MonoReflectionType *type)
        MONO_ARCH_SAVE_REGS;
 
        klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+       check_for_invalid_type (klass);
 
        return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
 }
@@ -5716,9 +5829,11 @@ ves_icall_Type_make_byref_type (MonoReflectionType *type)
 static MonoReflectionType *
 ves_icall_Type_MakePointerType (MonoReflectionType *type)
 {
-       MonoClass *pklass;
+       MonoClass *klass, *pklass;
 
-       MONO_ARCH_SAVE_REGS;
+       klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+       check_for_invalid_type (klass);
 
        pklass = mono_ptr_class_get (type->type);
 
@@ -5736,6 +5851,8 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
 
        MONO_ARCH_SAVE_REGS;
 
+       mono_class_init_or_throw (delegate_class);
+
        mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
 
        if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
@@ -5749,6 +5866,8 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
                /* Creating a trampoline would leak memory */
                func = mono_compile_method (method);
        } else {
+               if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
+                       method = mono_object_get_virtual_method (target, method);
                func = mono_create_ftnptr (mono_domain_get (),
                        mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE));
        }
@@ -6188,12 +6307,13 @@ ves_icall_System_Environment_get_Platform (void)
 #elif defined(__MACH__)
        /* OSX */
        //
-       // For compatibility with our client code, this will be 4 for a while.
-       // We will eventually move to 6 to match .NET, but it requires all client
-       // code to be updated and the documentation everywhere to be updated 
-       // first.
+       // Notice that the value is hidden from user code, and only exposed
+       // to mscorlib.   This is due to Mono's Unix/MacOS code predating the
+       // define and making assumptions based on Unix/128/4 values before there
+       // was a MacOS define.    Lots of code would assume that not-Unix meant
+       // Windows, but in this case, it would be OSX. 
        //
-       return 4;
+       return 6;
 #else
        /* Unix */
        return 4;
@@ -6239,7 +6359,7 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
  */
 #ifndef _MSC_VER
 #ifndef __MINGW32_VERSION
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined (__arm__)
 /* Apple defines this in crt_externs.h but doesn't provide that header for 
  * arm-apple-darwin9.  We'll manually define the symbol on Apple as it does
  * in fact exist on all implementations (so far) 
@@ -6445,7 +6565,7 @@ ves_icall_System_Environment_GetWindowsFolderPath (int folder)
 static MonoArray *
 ves_icall_System_Environment_GetLogicalDrives (void)
 {
-        gunichar2 buf [128], *ptr, *dname;
+        gunichar2 buf [256], *ptr, *dname;
        gunichar2 *u16;
        guint initial_size = 127, size = 128;
        gint ndrives;
@@ -6639,6 +6759,7 @@ ves_icall_Remoting_RemotingServices_GetVirtualMethod (
 
        method = rmethod->method;
        klass = mono_class_from_mono_type (rtype->type);
+       mono_class_init_or_throw (klass);
 
        if (MONO_CLASS_IS_INTERFACE (klass))
                return NULL;
@@ -6701,6 +6822,7 @@ ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClas
 
        domain = mono_object_domain (type);
        klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
 
        if (klass->rank >= 1) {
                g_assert (klass->rank == 1);
@@ -6792,6 +6914,40 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
        return mcpath;
 }
 
+static MonoString *
+get_bundled_app_config (void)
+{
+       const gchar *app_config;
+       MonoDomain *domain;
+       MonoString *file;
+       gchar *config_file;
+       gsize len;
+       gchar *module;
+
+       MONO_ARCH_SAVE_REGS;
+
+       domain = mono_domain_get ();
+       file = domain->setup->configuration_file;
+       if (!file)
+               return NULL;
+
+       // Retrieve config file and remove the extension
+       config_file = mono_string_to_utf8 (file);
+       len = strlen (config_file) - strlen (".config");
+       module = g_malloc0 (len + 1);
+       memcpy (module, config_file, len);
+       // Get the config file from the module name
+       app_config = mono_config_string_for_assembly_file (module);
+       // Clean-up
+       g_free (module);
+       g_free (config_file);
+
+       if (!app_config)
+               return NULL;
+
+       return mono_string_new (mono_domain_get (), app_config);
+}
+
 static MonoString *
 get_bundled_machine_config (void)
 {
@@ -6887,6 +7043,7 @@ ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
 
        domain = mono_object_domain (type);
        klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
 
        if (mono_class_is_nullable (klass))
                /* No arguments -> null */
@@ -6933,6 +7090,14 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
        if (klass == method->klass)
                return m;
 
+       /*This is possible if definition == FALSE.
+        * Do it here to be really sure we don't read invalid memory.
+        */
+       if (method->slot >= klass->vtable_size)
+               return m;
+
+       mono_class_setup_vtable (klass);
+
        result = klass->vtable [method->slot];
        if (result == NULL) {
                /* It is an abstract method */
@@ -7111,6 +7276,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType
        gpointer iter = NULL;
        MONO_ARCH_SAVE_REGS;
 
+       mono_class_init_or_throw (klass);
+
        while ((m = mono_class_get_methods (klass, &iter)))
                prelink_method (m);
 }
@@ -7280,8 +7447,6 @@ property_info_get_default_value (MonoReflectionProperty *property)
        const char *def_value;
        MonoObject *o;
 
-       g_assert (!prop->parent->image->dynamic);
-
        mono_class_init (prop->parent);
 
        if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT))
@@ -7298,13 +7463,16 @@ property_info_get_default_value (MonoReflectionProperty *property)
 static MonoBoolean
 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
 {
+       MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
        MonoCustomAttrInfo *cinfo;
        gboolean found;
 
+       mono_class_init_or_throw (attr_class);
+
        cinfo = mono_reflection_get_custom_attrs_info (obj);
        if (!cinfo)
                return FALSE;
-       found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
+       found = mono_custom_attrs_has_attr (cinfo, attr_class);
        if (!cinfo->cached)
                mono_custom_attrs_free (cinfo);
        return found;
@@ -7313,8 +7481,16 @@ custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
 static MonoArray*
 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
 {
-       MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
+       MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
+       MonoArray *res;
+       MonoError error;
 
+       if (attr_class)
+               mono_class_init_or_throw (attr_class);
+
+       res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
        if (mono_loader_get_last_error ()) {
                mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
                g_assert_not_reached ();