2010-07-10 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / icall.c
index 2318ccaad3458aa66e03e82fad2a8956cf6b8676..24c8accbc41618ed943ff799b18feea554d1afec 100644 (file)
@@ -24,7 +24,7 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
 #include <stdlib.h>
 #endif
 
 #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/io-layer/io-layer.h>
 #include <mono/utils/strtod.h>
 #include <mono/utils/monobitset.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-string.h>
+#include <mono/utils/mono-error-internals.h>
+#include <mono/utils/mono-mmap.h>
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
 #include <windows.h>
 #include <shlobj.h>
 #endif
 #include "decimal.h"
 
+extern MonoString* ves_icall_System_Environment_GetOSVersionString (void) MONO_INTERNAL;
+
 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
 
 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*)); \
-               (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
  */
@@ -255,6 +227,11 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
        ea = (gpointer*)((char*)this->vector + (pos * esize));
        va = (gpointer*)((char*)value + sizeof (MonoObject));
 
+       if (mono_class_is_nullable (ec)) {
+               mono_nullable_init ((guint8*)ea, value, ec);
+               return;
+       }
+
        if (!value) {
                memset (ea, 0,  esize);
                return;
@@ -545,9 +522,9 @@ 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;
-       mono_array_size_t *sizes, i;
+       uintptr_t *sizes, i;
        gboolean bounded = FALSE;
 
        MONO_ARCH_SAVE_REGS;
@@ -563,15 +540,18 @@ 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(mono_array_size_t) * 2);
+       sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
        for (i = 0; i < aklass->rank; ++i) {
                sizes [i] = mono_array_get (lengths, guint32, i);
                if (bounds)
@@ -580,7 +560,7 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *
                        sizes [i + aklass->rank] = 0;
        }
 
-       array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
+       array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank);
 
        return array;
 }
@@ -588,9 +568,9 @@ 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;
-       mono_array_size_t *sizes, i;
+       uintptr_t *sizes, i;
        gboolean bounded = FALSE;
 
        MONO_ARCH_SAVE_REGS;
@@ -607,15 +587,18 @@ 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(mono_array_size_t) * 2);
+       sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
        for (i = 0; i < aklass->rank; ++i) {
                sizes [i] = mono_array_get (lengths, guint64, i);
                if (bounds)
@@ -624,7 +607,7 @@ ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray
                        sizes [i + aklass->rank] = 0;
        }
 
-       array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
+       array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank);
 
        return array;
 }
@@ -641,7 +624,7 @@ static gint32
 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
 {
        gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
-       mono_array_size_t length;
+       uintptr_t length;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -717,6 +700,7 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
        if (source->bounds || dest->bounds)
                return FALSE;
 
+       /* there's no integer overflow since mono_array_length returns an unsigned integer */
        if ((dest_idx + length > mono_array_length (dest)) ||
                (source_idx + length > mono_array_length (source)))
                return FALSE;
@@ -808,7 +792,7 @@ ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpoin
 static void
 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
 {
-       MonoClass *ac;
+       MonoClass *ac, *ec;
        MonoArray *ao;
        gint32 esize;
        gpointer *ea;
@@ -817,11 +801,22 @@ ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpoin
 
        ao = (MonoArray *)this;
        ac = (MonoClass *)ao->obj.vtable->klass;
+       ec = ac->element_class;
 
        esize = mono_array_element_size (ac);
        ea = (gpointer*)((char*)ao->vector + (pos * esize));
 
-       memcpy (ea, value, esize);
+       if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
+               g_assert (esize == sizeof (gpointer));
+               mono_gc_wbarrier_generic_store (ea, *(gpointer*)value);
+       } else {
+               g_assert (ec->inited);
+               g_assert (esize == mono_class_value_size (ec, NULL));
+               if (ec->has_references)
+                       mono_gc_wbarrier_value_copy (ea, value, 1, ec);
+               else
+                       memcpy (ea, value, esize);
+       }
 }
 
 static void
@@ -930,16 +925,17 @@ static void
 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
 {
        MonoClass *klass;
-
-       MONO_ARCH_SAVE_REGS;
+       MonoVTable *vtable;
 
        MONO_CHECK_ARG_NULL (handle);
 
        klass = mono_class_from_mono_type (handle);
        MONO_CHECK_ARG (handle, klass);
 
+       vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE);
+
        /* This will call the type constructor */
-       mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
+       mono_runtime_class_init (vtable);
 }
 
 static void
@@ -950,10 +946,34 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (M
        mono_image_check_for_module_cctor (image);
        if (image->has_module_cctor) {
                MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
-               mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
+               /*It's fine to raise the exception here*/
+               mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass, TRUE));
        }
 }
 
+static MonoBoolean
+ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
+{
+       guint8 *stack_addr;
+       guint8 *current;
+       size_t stack_size;
+       /* later make this configurable and per-arch */
+       int min_size = 4096 * 4 * sizeof (void*);
+       mono_thread_get_stack_bounds (&stack_addr, &stack_size);
+       /* if we have no info we are optimistic and assume there is enough room */
+       if (!stack_addr)
+               return TRUE;
+       current = (guint8 *)&stack_addr;
+       if (current > stack_addr) {
+               if ((current - stack_addr) < min_size)
+                       return FALSE;
+       } else {
+               if (current - (stack_addr - stack_size) < min_size)
+                       return FALSE;
+       }
+       return TRUE;
+}
+
 static MonoObject *
 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
 {
@@ -1013,7 +1033,7 @@ ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fi
 
        if (values) {
                int i;
-               *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
+               mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
                for (i = 0; i < count; ++i)
                        mono_array_setref (*fields, i, values [i]);
        } else {
@@ -1125,7 +1145,7 @@ ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray
 
        if (values) {
                int i;
-               *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
+               mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
                for (i = 0; i < count; ++i)
                        mono_array_setref (*fields, i, values [i]);
                return FALSE;
@@ -1301,19 +1321,27 @@ type_from_name (const char *str, MonoBoolean ignoreCase)
                 *        Dec 10, 2005 - Martin.
                 */
 
-               if (dest)
+               if (dest) {
                        assembly = dest->klass->image->assembly;
-               else {
+                       type_resolve = TRUE;
+               } else {
                        g_warning (G_STRLOC);
                }
        }
 
-       if (assembly)
+       if (assembly) {
+               /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
                type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
-       
+       }
+
        if (!info.assembly.name && !type) /* try mscorlib */
                type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
 
+       if (assembly && !type && type_resolve) {
+               type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
+               type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
+       }
+
        mono_reflection_free_type_info (&info);
        g_free (temp_str);
 
@@ -1364,11 +1392,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);
 }
 
@@ -1506,12 +1532,42 @@ 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;
 
        return mono_class_is_subclass_of (klass, klassc, check_interfaces);
 }
 
+static gboolean
+mono_type_is_primitive (MonoType *type)
+{
+       return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
+                       type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
+}
+
+static MonoType*
+mono_type_get_underlying_type_ignore_byref (MonoType *type)
+{
+       if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
+               return mono_class_enum_basetype (type->data.klass);
+       if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
+               return mono_class_enum_basetype (type->data.generic_class->container_class);
+       return type;
+}
+
 static guint32
 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
 {
@@ -1528,9 +1584,34 @@ 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);
 
-       if (type->type->byref && !c->type->byref)
+       mono_class_init_or_throw (klass);
+       mono_class_init_or_throw (klassc);
+
+       if (type->type->byref ^ c->type->byref)
                return FALSE;
 
+       if (type->type->byref) {
+               MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
+               MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
+
+               klass = mono_class_from_mono_type (t);
+               klassc = mono_class_from_mono_type (ot);
+
+               if (mono_type_is_primitive (t)) {
+                       return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
+               } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
+                       return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
+               } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
+                       return t->type == ot->type;
+               } else {
+                        if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
+                                return FALSE;
+
+                        if (klass->valuetype)
+                               return klass == klassc;
+                       return klass->valuetype == klassc->valuetype;
+               }
+       }
        return mono_class_is_assignable_from (klass, klassc);
 }
 
@@ -1538,6 +1619,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;
 }
 
@@ -1545,9 +1627,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;
 }
 
@@ -1577,27 +1656,33 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *
 }
 
 static MonoReflectionField*
-ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
+ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
 {
+       gboolean found = FALSE;
+       MonoClass *klass;
+       MonoClass *k;
+
        g_assert (handle);
 
-       if (!klass)
+       if (!type) {
                klass = handle->parent;
+       } else {
+               klass = mono_class_from_mono_type (type);
 
-       /* FIXME: check that handle is a field of klass or of a parent: return null
-        * and throw the exception in managed code.
-        */
-       return mono_field_get_object (mono_domain_get (), klass, handle);
-}
-
-static MonoReflectionField*
-ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
-{
-       MONO_ARCH_SAVE_REGS;
+               /* Check that the field belongs to the class */
+               for (k = klass; k; k = k->parent) {
+                       if (k == handle->parent) {
+                               found = TRUE;
+                               break;
+                       }
+               }
 
-       g_assert (handle);
+               if (!found)
+                       /* The managed code will throw the exception */
+                       return NULL;
+       }
 
-       return mono_field_get_object (mono_domain_get (), handle->parent, handle);
+       return mono_field_get_object (mono_domain_get (), klass, handle);
 }
 
 static MonoArray*
@@ -1620,9 +1705,9 @@ ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
                g_assert (mono_loader_get_last_error ());
                mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
        }
-       
-       info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
-       info->ret = mono_type_get_object (domain, sig->ret);
+
+       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));
        info->attrs = method->flags;
        info->implattrs = method->iflags;
        if (sig->call_convention == MONO_CALL_DEFAULT)
@@ -1686,129 +1771,18 @@ ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean decla
 static MonoObject *
 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
 {      
-       MonoObject *o;
+       MonoClass *fklass = field->klass;
        MonoClassField *cf = field->field;
-       MonoClass *klass;
-       MonoVTable *vtable;
-       MonoType *t;
-       MonoDomain *domain = mono_object_domain (field); 
-       gchar *v;
-       gboolean is_static = FALSE;
-       gboolean is_ref = FALSE;
+       MonoDomain *domain = mono_object_domain (field);
 
-       MONO_ARCH_SAVE_REGS;
-
-       if (field->klass->image->assembly->ref_only)
+       if (fklass->image->assembly->ref_only)
                mono_raise_exception (mono_get_exception_invalid_operation (
                                        "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
-       
+
        if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
                mono_security_core_clr_ensure_reflection_access_field (cf);
 
-       mono_class_init (field->klass);
-
-       if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
-               is_static = TRUE;
-
-       if (obj && !is_static) {
-               /* Check that the field belongs to the object */
-               gboolean found = FALSE;
-               MonoClass *k;
-
-               for (k = obj->vtable->klass; k; k = k->parent) {
-                       if (k == cf->parent) {
-                               found = TRUE;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", mono_field_get_name (cf), cf->parent->name, obj->vtable->klass->name);
-                       MonoException *ex = mono_get_exception_argument (NULL, msg);
-                       g_free (msg);
-                       mono_raise_exception (ex);
-               }
-       }
-
-       t = mono_type_get_underlying_type (cf->type);
-       switch (t->type) {
-       case MONO_TYPE_STRING:
-       case MONO_TYPE_OBJECT:
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_ARRAY:
-       case MONO_TYPE_SZARRAY:
-               is_ref = TRUE;
-               break;
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I1:
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I2:
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_U:
-       case MONO_TYPE_I:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_R4:
-       case MONO_TYPE_U8:
-       case MONO_TYPE_I8:
-       case MONO_TYPE_R8:
-       case MONO_TYPE_VALUETYPE:
-               is_ref = t->byref;
-               break;
-       case MONO_TYPE_GENERICINST:
-               if (mono_type_generic_inst_is_valuetype (t)) {
-                       is_ref = t->byref;
-               } else {
-                       is_ref = TRUE;
-               }
-               break;
-       default:
-               g_error ("type 0x%x not handled in "
-                        "ves_icall_Monofield_GetValue", t->type);
-               return NULL;
-       }
-
-       vtable = NULL;
-       if (is_static) {
-               vtable = mono_class_vtable (domain, cf->parent);
-               if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
-                       mono_runtime_class_init (vtable);
-       }
-       
-       if (is_ref) {
-               if (is_static) {
-                       mono_field_static_get_value (vtable, cf, &o);
-               } else {
-                       mono_field_get_value (obj, cf, &o);
-               }
-               return o;
-       }
-
-       if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
-               MonoClass *nklass = mono_class_from_mono_type (cf->type);
-               guint8 *buf;
-
-               /* Convert the Nullable structure into a boxed vtype */
-               if (is_static)
-                       buf = (guint8*)vtable->data + cf->offset;
-               else
-                       buf = (guint8*)obj + cf->offset;
-
-               return mono_nullable_box (buf, nklass);
-       }
-
-       /* boxed value type */
-       klass = mono_class_from_mono_type (cf->type);
-       o = mono_object_new (domain, klass);
-       v = ((gchar *) o) + sizeof (MonoObject);
-       if (is_static) {
-               mono_field_static_get_value (vtable, cf, v);
-       } else {
-               mono_field_get_value (obj, cf, v);
-       }
-
-       return o;
+       return mono_field_get_value_object (domain, cf, obj);
 }
 
 static void
@@ -1886,7 +1860,7 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
        }
 
        if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
-               MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
+               MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, TRUE);
                if (!vtable->initialized)
                        mono_runtime_class_init (vtable);
                mono_field_static_set_value (vtable, cf, v);
@@ -1920,6 +1894,7 @@ ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
 
        def_value = mono_class_get_field_default_value (field, &def_type);
 
+       /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
        switch (def_type) {
        case MONO_TYPE_U1:
        case MONO_TYPE_I1:
@@ -2014,90 +1989,128 @@ ves_icall_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
 
        MONO_ARCH_SAVE_REGS;
 
-       info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
-       info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
+       MONO_STRUCT_SETREF (info, reflected_type, mono_type_get_object (domain, &event->klass->byval_arg));
+       MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &event->event->parent->byval_arg));
 
-       info->name = mono_string_new (domain, event->event->name);
+       MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
        info->attrs = event->event->attrs;
-       info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
-       info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
-       info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
+       MONO_STRUCT_SETREF (info, add_method, event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL);
+       MONO_STRUCT_SETREF (info, remove_method, event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL);
+       MONO_STRUCT_SETREF (info, raise_method, event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL);
 
+#ifndef MONO_SMALL_CONFIG
        if (event->event->other) {
                int i, n = 0;
                while (event->event->other [n])
                        n++;
-               info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
+               MONO_STRUCT_SETREF (info, other_methods, mono_array_new (domain, mono_defaults.method_info_class, n));
 
                for (i = 0; i < n; i++)
                        mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
        }               
+#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)
 {
-       MonoDomain *domain = mono_object_domain (type); 
-       MonoArray *intf;
-       GPtrArray *ifaces = NULL;
-       int i;
+       MonoError error;
        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);
-               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);
-               }
-       }
-       mono_bitset_free (slots);
+       len = g_hash_table_size (iface_hash);
+       if (len == 0)
+               return mono_array_new_cached (data.domain, mono_defaults.monotype_class, 0);
 
-       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
 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
 {
+       gboolean variance_used;
        MonoClass *class = mono_class_from_mono_type (type->type);
        MonoClass *iclass = mono_class_from_mono_type (iface->type);
        MonoReflectionMethod *member;
@@ -2107,19 +2120,19 @@ 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);
 
-       /* type doesn't implement iface: the exception is thrown in managed code */
-       if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
-                       return;
+       ioffset = mono_class_interface_offset_with_variance (class, iclass, &variance_used);
+       if (ioffset == -1)
+               return;
 
        len = mono_class_num_methods (iclass);
-       ioffset = mono_class_interface_offset (class, iclass);
        domain = mono_object_domain (type);
-       *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
-       *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
-       iter = NULL;
+       mono_gc_wbarrier_generic_store (targets, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len));
+       mono_gc_wbarrier_generic_store (methods, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len));
        iter = NULL;
        while ((method = mono_class_get_methods (iclass, &iter))) {
                member = mono_method_get_object (domain, method, iclass);
@@ -2135,6 +2148,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;
@@ -2156,6 +2170,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
@@ -2173,9 +2188,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;
 }
 
@@ -2207,7 +2219,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);
 }
@@ -2216,8 +2228,7 @@ static MonoReflectionModule*
 ves_icall_MonoType_get_Module (MonoReflectionType *type)
 {
        MonoClass *class = mono_class_from_mono_type (type->type);
-
-       MONO_ARCH_SAVE_REGS;
+       mono_class_init_or_throw (class);
 
        return mono_module_get_object (mono_object_domain (type), class->image);
 }
@@ -2228,7 +2239,7 @@ 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;
+       mono_class_init_or_throw (class);
 
        return mono_assembly_get_object (domain, class->image->assembly);
 }
@@ -2244,39 +2255,21 @@ ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
        if (type->type->byref)
                return NULL;
        if (type->type->type == MONO_TYPE_VAR)
-               class = type->type->data.generic_param->owner->owner.klass;
+               class = mono_type_get_generic_param_owner (type->type)->owner.klass;
        else if (type->type->type == MONO_TYPE_MVAR)
-               class = type->type->data.generic_param->owner->owner.method->klass;
+               class = mono_type_get_generic_param_owner (type->type)->owner.method->klass;
        else
                class = mono_class_from_mono_type (type->type)->nested_in;
 
        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);
@@ -2295,8 +2288,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;
 
@@ -2309,9 +2300,13 @@ ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
 static gint32
 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
 {
-       MonoClass *class = mono_class_from_mono_type (type->type);
+       MonoClass *class;
 
-       MONO_ARCH_SAVE_REGS;
+       if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY)
+               mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type"));
+
+       class = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (class);
 
        return class->rank;
 }
@@ -2322,11 +2317,12 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
        MonoArray *res;
        MonoClass *klass, *pklass;
        MonoDomain *domain = mono_object_domain (type);
-       MonoVTable *array_vtable = mono_class_vtable (domain, mono_array_class_get_cached (mono_defaults.systemtype_class, 1));
+       MonoVTable *array_vtable = mono_class_vtable_full (domain, mono_array_class_get_cached (mono_defaults.systemtype_class, 1), TRUE);
        int i;
        MONO_ARCH_SAVE_REGS;
 
        klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
 
        if (klass->generic_container) {
                MonoGenericContainer *container = klass->generic_container;
@@ -2359,7 +2355,6 @@ ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
                return FALSE;
 
        klass = mono_class_from_mono_type (type->type);
-
        return klass->generic_container != NULL;
 }
 
@@ -2373,14 +2368,19 @@ ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
                return NULL;
 
        klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+
        if (klass->generic_container) {
                return type; /* check this one */
        }
        if (klass->generic_class) {
                MonoClass *generic_class = klass->generic_class->container_class;
+               gpointer tb;
+
+               tb = mono_class_get_ref_info (generic_class);
 
-               if (generic_class->wastypebuilder && generic_class->reflection_info)
-                       return generic_class->reflection_info;
+               if (generic_class->wastypebuilder && tb)
+                       return tb;
                else
                        return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
        }
@@ -2393,7 +2393,8 @@ ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
        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);
@@ -2421,6 +2422,7 @@ ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
                return FALSE;
 
        klass = mono_class_from_mono_type (type->type);
+
        return klass->generic_class != NULL;
 }
 
@@ -2437,458 +2439,122 @@ ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
                return FALSE;
 
        klass = mono_class_from_mono_type (type->type);
-       return klass->generic_class != NULL || klass->generic_container != NULL;
-}
-
-static gint32
-ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       if (!IS_MONOTYPE (type))
-               return -1;
-
-       if (is_generic_parameter (type->type))
-               return type->type->data.generic_param->num;
-       return -1;
-}
-
-static GenericParameterAttributes
-ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       g_assert (IS_MONOTYPE (type));
-       g_assert (is_generic_parameter (type->type));
-       return type->type->data.generic_param->flags;
-}
-
-static MonoArray *
-ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
-{
-       MonoGenericParam *param;
-       MonoDomain *domain;
-       MonoClass **ptr;
-       MonoArray *res;
-       int i, count;
-
-       MONO_ARCH_SAVE_REGS;
-
-       g_assert (IS_MONOTYPE (type));
-
-       domain = mono_object_domain (type);
-       param = type->type->data.generic_param;
-       for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
-               ;
-
-       res = mono_array_new (domain, mono_defaults.monotype_class, count);
-       for (i = 0; i < count; i++)
-               mono_array_setref (res, i, mono_type_get_object (domain, &param->constraints [i]->byval_arg));
-
-
-       return res;
-}
-
-static MonoBoolean
-ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
-{
-       MONO_ARCH_SAVE_REGS;
-       return is_generic_parameter (type->type);
-}
-
-static MonoBoolean
-ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
-{
-       MONO_ARCH_SAVE_REGS;
-       return is_generic_parameter (tb->type.type);
-}
-
-static void
-ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
-                                                                          MonoReflectionType *t)
-{
-       enumtype->type = t->type;
-}
-
-static MonoReflectionType*
-ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
-{
-       MonoDynamicGenericClass *gclass;
-       MonoReflectionType *parent = NULL, *res;
-       MonoDomain *domain;
-       MonoType *inflated;
-       MonoClass *klass;
-
-
-       MONO_ARCH_SAVE_REGS;
-
-       g_assert (type->type.type->data.generic_class->is_dynamic);
-       gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
-
-       domain = mono_object_domain (type);
-       klass = mono_class_from_mono_type (type->generic_type->type.type);
-
-       if (!klass->generic_class && !klass->generic_container)
-               return NULL;
-
-       parent = monotype_cast (type->generic_type->parent);
-
-       if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
-               return NULL;
-
-       inflated = mono_class_inflate_generic_type (
-               parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
-
-       res = mono_type_get_object (domain, inflated);
-       mono_metadata_free_type (inflated);
-       return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
-{
-       static MonoClass *System_Reflection_MonoGenericClass;
-       MonoGenericClass *gclass;
-       MonoReflectionTypeBuilder *tb = NULL;
-       MonoClass *klass = NULL;
-       MonoDomain *domain;
-       MonoArray *res;
-       int icount, i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (!System_Reflection_MonoGenericClass) {
-               System_Reflection_MonoGenericClass = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
-               g_assert (System_Reflection_MonoGenericClass);
-       }
-
-       domain = mono_object_domain (type);
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       tb = type->generic_type;
-       icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
-
-       res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
-
-       for (i = 0; i < icount; i++) {
-               MonoReflectionType *iface;
-               MonoType *it;
-
-               if (tb) {
-                       iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
-                       it = iface->type;
-               } else
-                       it = &klass->interfaces [i]->byval_arg;
-
-               it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
-
-               iface = mono_type_get_object (domain, it);
-               mono_array_setref (res, i, iface);
-               mono_metadata_free_type (it);
-       }
-
-       return res;
-}
-
-static MonoReflectionMethod*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type, 
-                                                           MonoReflectionMethod* generic)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       domain = mono_object_domain (type);
-
-       for (i = 0; i < dgclass->count_methods; i++)
-               if (generic->method->token == dgclass->methods [i]->token)
-                        return mono_method_get_object (domain, dgclass->methods [i], NULL);
-
-       return NULL;
-}
-
-static MonoReflectionMethod*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type, 
-                                                                MonoReflectionMethod* generic)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       domain = mono_object_domain (type);
-
-       for (i = 0; i < dgclass->count_ctors; i++)
-               if (generic->method->token == dgclass->ctors [i]->token)
-                        return mono_method_get_object (domain, dgclass->ctors [i], NULL);
-
-       return NULL;
-}
-
-
-static MonoReflectionField*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type, 
-                                                          MonoString* generic_name)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-        MonoClass *refclass;
-       char *utf8_name = mono_string_to_utf8 (generic_name);
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (type->type.type);
-
-       domain = mono_object_domain (type);
-
-       for (i = 0; i < dgclass->count_fields; i++)
-               if (strcmp (utf8_name, mono_field_get_name (&dgclass->fields [i])) == 0) {
-                       g_free (utf8_name);
-                        return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
-               }
-       
-       g_free (utf8_name);
-
-       return NULL;
-}
-
-
-static MonoReflectionMethod*
-ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type, 
-                                                   MonoReflectionMethod* generic)
-{
-       MonoDomain *domain; 
-       MonoClass *klass;
-       MonoMethod *method;
-       gpointer iter;
-               
-       MONO_ARCH_SAVE_REGS;
-
-       domain = ((MonoObject *)type)->vtable->domain;
-
-       klass = mono_class_from_mono_type (type->type);
-
-       iter = NULL;
-       while ((method = mono_class_get_methods (klass, &iter))) {
-                if (method->token == generic->method->token)
-                        return mono_method_get_object (domain, method, klass);
-        }
-
-        return NULL;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
-                                      MonoReflectionType *reflected_type)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
-
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
-
-       for (i = 0; i < dgclass->count_methods; i++)
-               mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
-
-       return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
-                                           MonoReflectionType *reflected_type)
-{
-       static MonoClass *System_Reflection_ConstructorInfo;
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (!System_Reflection_ConstructorInfo)
-               System_Reflection_ConstructorInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
-
-       domain = mono_object_domain (type);
-       res = mono_array_new_cached (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
-
-       for (i = 0; i < dgclass->count_ctors; i++)
-               mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
-
-       return res;
+       return klass->generic_class != NULL || klass->generic_container != NULL;
 }
 
-static MonoArray*
-ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
-                                     MonoReflectionType *reflected_type)
+static gint32
+ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
 {
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
        MONO_ARCH_SAVE_REGS;
 
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
+       if (!IS_MONOTYPE (type))
+               return -1;
 
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
+       if (is_generic_parameter (type->type))
+               return mono_type_get_generic_param_num (type->type);
+       return -1;
+}
 
-       for (i = 0; i < dgclass->count_fields; i++)
-               mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
+static GenericParameterAttributes
+ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
+{
+       MONO_ARCH_SAVE_REGS;
 
-       return res;
+       g_assert (IS_MONOTYPE (type));
+       g_assert (is_generic_parameter (type->type));
+       return mono_generic_param_info (type->type->data.generic_param)->flags;
 }
 
-static MonoArray*
-ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
-                                         MonoReflectionType *reflected_type)
+static MonoArray *
+ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
 {
-       static MonoClass *System_Reflection_PropertyInfo;
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
+       MonoGenericParamInfo *param_info;
        MonoDomain *domain;
-       MonoClass *refclass;
+       MonoClass **ptr;
        MonoArray *res;
-       int i;
+       int i, count;
 
        MONO_ARCH_SAVE_REGS;
 
-       if (!System_Reflection_PropertyInfo)
-               System_Reflection_PropertyInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "PropertyInfo");
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
+       g_assert (IS_MONOTYPE (type));
 
        domain = mono_object_domain (type);
-       res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
+       param_info = mono_generic_param_info (type->type->data.generic_param);
+       for (count = 0, ptr = param_info->constraints; ptr && *ptr; ptr++, count++)
+               ;
+
+       res = mono_array_new (domain, mono_defaults.monotype_class, count);
+       for (i = 0; i < count; i++)
+               mono_array_setref (res, i, mono_type_get_object (domain, &param_info->constraints [i]->byval_arg));
 
-       for (i = 0; i < dgclass->count_properties; i++)
-               mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
 
        return res;
 }
 
-static MonoArray*
-ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
-                                     MonoReflectionType *reflected_type)
+static MonoBoolean
+ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
 {
-       static MonoClass *System_Reflection_EventInfo;
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
+       MONO_ARCH_SAVE_REGS;
+       return is_generic_parameter (type->type);
+}
 
+static MonoBoolean
+ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
+{
        MONO_ARCH_SAVE_REGS;
+       return is_generic_parameter (tb->type.type);
+}
 
-       if (!System_Reflection_EventInfo)
-               System_Reflection_EventInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "EventInfo");
+static void
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
+                                                                          MonoReflectionType *t)
+{
+       enumtype->type = t->type;
+}
 
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
+static MonoReflectionMethod*
+ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type, 
+                                                   MonoReflectionMethod* generic)
+{
+       MonoDomain *domain; 
+       MonoClass *klass;
+       MonoMethod *method;
+       gpointer iter;
+               
+       MONO_ARCH_SAVE_REGS;
 
-       refclass = mono_class_from_mono_type (reflected_type->type);
+       domain = ((MonoObject *)type)->vtable->domain;
 
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
+       klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
 
-       for (i = 0; i < dgclass->count_events; i++)
-               mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
+       iter = NULL;
+       while ((method = mono_class_get_methods (klass, &iter))) {
+                if (method->token == generic->method->token)
+                        return mono_method_get_object (domain, method, klass);
+        }
 
-       return res;
+        return NULL;
 }
 
-static MonoReflectionType*
-ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass *type,
-                                     MonoReflectionType *target)
-{
-       MonoType *res_type;
-       MonoClass *gklass;
-       MonoReflectionType *res;
-
-       MONO_ARCH_SAVE_REGS;
 
-       gklass = mono_class_from_mono_type (type->type.type);
-       res_type = mono_class_inflate_generic_type (target->type, mono_class_get_context (gklass));
-       res = mono_type_get_object (mono_object_domain (type), res_type);
-       mono_metadata_free_type (res_type);
-       return res;
-}
 
 static MonoReflectionMethod *
-ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
+ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *ref_type)
 {
        MonoMethod *method;
-       MonoClass *klass;
+       MonoType *type = ref_type->type;
 
        MONO_ARCH_SAVE_REGS;
 
-       if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
+       if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR))
+               mono_raise_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
+       if (type->type == MONO_TYPE_VAR)
                return NULL;
 
-       method = type->type->data.generic_param->owner->owner.method;
+       method = mono_type_get_generic_param_owner (type)->owner.method;
        g_assert (method);
-       klass = mono_class_from_mono_type (type->type);
-       return mono_method_get_object (mono_object_domain (type), method, klass);
+       return mono_method_get_object (mono_object_domain (ref_type), method, method->klass);
 }
 
 static MonoReflectionDllImportAttribute*
@@ -2908,7 +2574,7 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
        const char *scope = NULL;
        guint32 flags;
 
-       if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+       if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
                return NULL;
 
        if (!DllImportAttributeClass) {
@@ -2926,6 +2592,11 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
                        import = method_aux->dllentry;
                        scope = method_aux->dll;
                }
+
+               if (!import || !scope) {
+                       mono_raise_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
+                       return NULL;
+               }
        }
        else {
                if (piinfo->implmap_idx) {
@@ -2995,7 +2666,9 @@ ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
 
        if (imethod->context.class_inst) {
                MonoClass *klass = ((MonoMethod *) imethod)->klass;
-               result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass));
+               /*Generic methods gets the context of the GTD.*/
+               if (mono_class_get_context (klass))
+                       result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass));
        }
 
        return mono_method_get_object (mono_object_domain (method), result, NULL);
@@ -3076,9 +2749,14 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
                mono_security_core_clr_ensure_reflection_access_method (m);
 
        if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
+               if (!mono_class_vtable_full (mono_object_domain (method), m->klass, FALSE)) {
+                       mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
+                       return NULL;
+               }
+
                if (this) {
                        if (!mono_object_isinst (this, m->klass)) {
-                               *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type.");
+                               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type."));
                                return NULL;
                        }
                        m = mono_object_get_virtual_method (this, m);
@@ -3086,35 +2764,36 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
                        if (m->klass->valuetype)
                                obj = mono_object_unbox (this);
                } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
-                       *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target.");
+                       mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
                        return NULL;
                }
        }
 
        pcount = params? mono_array_length (params): 0;
        if (pcount != mono_method_signature (m)->param_count) {
-               *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException");
+               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
                return NULL;
        }
 
        if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) {
-               *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
+               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class."));
                return NULL;
        }
 
        if (m->klass->image->assembly->ref_only) {
-               *exc = mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
+               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
                return NULL;
        }
        
        if (m->klass->rank && !strcmp (m->name, ".ctor")) {
                int i;
-               mono_array_size_t *lengths;
-               mono_array_size_t *lower_bounds;
+               uintptr_t *lengths;
+               intptr_t *lower_bounds;
                pcount = mono_array_length (params);
-               lengths = alloca (sizeof (mono_array_size_t) * pcount);
+               lengths = alloca (sizeof (uintptr_t) * pcount);
+               /* Note: the synthetized array .ctors have int32 as argument type */
                for (i = 0; i < pcount; ++i)
-                       lengths [i] = *(mono_array_size_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
+                       lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
 
                if (m->klass->rank == pcount) {
                        /* Only lengths provided. */
@@ -3122,7 +2801,7 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
                } else {
                        g_assert (pcount == (m->klass->rank * 2));
                        /* lower bounds are first. */
-                       lower_bounds = lengths;
+                       lower_bounds = (intptr_t*)lengths;
                        lengths += m->klass->rank;
                }
 
@@ -3171,7 +2850,7 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
                                                result = *((gpointer *)((char *)this + field->offset));
                                
                                        out_args = mono_array_new (domain, mono_defaults.object_class, 1);
-                                       *outArgs = out_args;
+                                       mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
                                        mono_array_setref (out_args, 0, result);
                                        g_free (str);
                                        return NULL;
@@ -3208,17 +2887,14 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
 
                                        if (field_klass->valuetype) {
                                                size = mono_type_size (field->type, &align);
-#ifdef HAVE_SGEN_GC
+                                               g_assert (size == mono_class_value_size (field_klass, NULL));
                                                mono_gc_wbarrier_value_copy ((char *)this + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
-#endif
-                                               memcpy ((char *)this + field->offset, 
-                                                       ((char *)val) + sizeof (MonoObject), size);
                                        } else {
                                                mono_gc_wbarrier_set_field (this, (char*)this + field->offset, val);
                                        }
                                
                                        out_args = mono_array_new (domain, mono_defaults.object_class, 0);
-                                       *outArgs = out_args;
+                                       mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
 
                                        g_free (str);
                                        return NULL;
@@ -3257,7 +2933,7 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
                }
        }
 
-       *outArgs = out_args;
+       mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
 
        return result;
 }
@@ -3328,6 +3004,7 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
        MonoDomain *domain; 
        MonoClass *enumc, *objc;
        MonoObject *res;
+       MonoType *etype;
        guint64 val;
        
        MONO_ARCH_SAVE_REGS;
@@ -3337,6 +3014,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)
@@ -3344,9 +3024,14 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
        if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
                mono_raise_exception (mono_get_exception_argument ("value", "The value passed in must be an enum base or an underlying type for an enum, such as an Int32."));
 
+       etype = mono_class_enum_basetype (enumc);
+       if (!etype)
+               /* MS throws this for typebuilders */
+               mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
+
        res = mono_object_new (domain, enumc);
        val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? mono_class_enum_basetype (objc)->type: objc->byval_arg.type);
-       write_enum_value ((char *)res + sizeof (MonoObject), mono_class_enum_basetype (enumc)->type, val);
+       write_enum_value ((char *)res + sizeof (MonoObject), etype->type, val);
 
        return res;
 }
@@ -3381,9 +3066,20 @@ ves_icall_System_Enum_get_value (MonoObject *this)
 static MonoReflectionType *
 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
 {
+       MonoType *etype;
+       MonoClass *klass;
+
        MONO_ARCH_SAVE_REGS;
 
-       return mono_type_get_object (mono_object_domain (type), 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"));
+
+       return mono_type_get_object (mono_object_domain (type), etype);
 }
 
 static int
@@ -3480,11 +3176,13 @@ ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
 
        MONO_ARCH_SAVE_REGS;
 
-       info->utype = mono_type_get_object (domain, mono_class_enum_basetype (enumc));
+       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;
-       info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
-       info->values = mono_array_new (domain, enumc, nvalues);
-       
+       MONO_STRUCT_SETREF (info, names, mono_array_new (domain, mono_defaults.string_class, nvalues));
+       MONO_STRUCT_SETREF (info, values, mono_array_new (domain, enumc, nvalues));
+
        crow = -1;
        iter = NULL;
        while ((field = mono_class_get_fields (enumc, &iter))) {
@@ -3556,15 +3254,14 @@ ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bfl
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        domain = ((MonoObject *)type)->vtable->domain;
        klass = startklass = mono_class_from_mono_type (type->type);
-
-       MONO_ARCH_SAVE_REGS;
+       mono_class_init_or_throw (klass);
 
        if (!name)
                mono_raise_exception (mono_get_exception_argument_null ("name"));
        if (type->type->byref)
                return NULL;
 
-       compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
 
 handle_parent:
        if (klass->exception_type != MONO_EXCEPTION_NONE)
@@ -3637,6 +3334,9 @@ ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, Mon
        klass = startklass = mono_class_from_mono_type (type->type);
        refklass = mono_class_from_mono_type (reftype->type);
 
+       mono_class_init_or_throw (klass);
+       mono_class_init_or_throw (refklass);
+
        mono_ptr_array_init (tmp_array, 2);
        
 handle_parent: 
@@ -3712,14 +3412,14 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        gpointer iter;
        MonoObject *member;
        int i, len, match, nslots;
+       /*FIXME, use MonoBitSet*/
        guint32 method_slots_default [8];
-       guint32 *method_slots;
+       guint32 *method_slots = NULL;
        gchar *mname = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        MonoVTable *array_vtable;
+       MonoException *ex;
        MonoPtrArray tmp_array;
-               
-       MONO_ARCH_SAVE_REGS;
 
        mono_ptr_array_init (tmp_array, 4);
 
@@ -3730,34 +3430,43 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        }
 
        domain = ((MonoObject *)type)->vtable->domain;
-       array_vtable = mono_class_vtable (domain, MethodInfo_array);
+       array_vtable = mono_class_vtable_full (domain, MethodInfo_array, TRUE);
        if (type->type->byref)
                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);
+
+       mono_class_init_or_throw (klass);
+       mono_class_init_or_throw (refklass);
+
        len = 0;
        if (name != NULL) {
                mname = mono_string_to_utf8 (name);
-               compare_func = (ignore_case) ? g_strcasecmp : strcmp;
+               compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
        }
 
        /* An optimization for calls made from Delegate:CreateDelegate () */
        if (klass->delegate && mname && !strcmp (mname, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
                method = mono_get_delegate_invoke (klass);
+               if (mono_loader_get_last_error ())
+                       goto loader_error;
 
                member = (MonoObject*)mono_method_get_object (domain, method, refklass);
-               
+
                res = mono_array_new_specific (array_vtable, 1);
                mono_array_setref (res, 0, member);
+               g_free (mname);
                return res;
        }
 
        mono_class_setup_vtable (klass);
+       if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+               goto loader_error;
 
        if (is_generic_parameter (type->type))
-               nslots = klass->parent->vtable_size;
+               nslots = mono_class_get_vtable_size (klass->parent);
        else
-               nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
+               nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
        if (nslots >= sizeof (method_slots_default) * 8) {
                method_slots = g_new0 (guint32, nslots / 32 + 1);
        } else {
@@ -3766,12 +3475,20 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        }
 handle_parent:
        mono_class_setup_vtable (klass);
-       if (klass->exception_type != MONO_EXCEPTION_NONE)
-               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 ((method = mono_class_get_methods (klass, &iter))) {
                match = 0;
+               if (method->slot != -1) {
+                       g_assert (method->slot < nslots);
+                       if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
+                               continue;
+                       if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
+                               method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
+               }
+
                if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
                        continue;
                if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
@@ -3801,12 +3518,6 @@ handle_parent:
                }
                
                match = 0;
-               if (method->slot != -1) {
-                       g_assert (method->slot < nslots);
-                       if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
-                               continue;
-                       method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
-               }
                
                member = (MonoObject*)mono_method_get_object (domain, method, refklass);
                
@@ -3826,6 +3537,20 @@ handle_parent:
 
        mono_ptr_array_destroy (tmp_array);
        return res;
+
+loader_error:
+       g_free (mname);
+       if (method_slots != method_slots_default)
+               g_free (method_slots);
+       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 MonoArray*
@@ -3851,6 +3576,9 @@ 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);
 
+       mono_class_init_or_throw (klass);
+       mono_class_init_or_throw (refklass);
+
        if (klass->exception_type != MONO_EXCEPTION_NONE)
                mono_raise_exception (mono_class_get_exception_for_failure (klass));
 
@@ -3959,9 +3687,13 @@ 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);
+       mono_class_init_or_throw (klass);
+
+
+
        if (name != NULL) {
                propname = mono_string_to_utf8 (name);
-               compare_func = (ignore_case) ? g_strcasecmp : strcmp;
+               compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
        }
 
        mono_class_setup_vtable (klass);
@@ -4048,6 +3780,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;
 
@@ -4057,13 +3790,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;
@@ -4081,21 +3817,20 @@ handle_parent:
                                if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
                                        continue;
                        }
-               }
-               else
-                       if (!(bflags & BFLAGS_NonPublic))
-                               continue;
 
-               if (method->flags & METHOD_ATTRIBUTE_STATIC) {
-                       if (!(bflags & BFLAGS_Static))
-                               continue;
-                       if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
-                               continue;
-               } else {
-                       if (!(bflags & BFLAGS_Instance))
+                       if (method->flags & METHOD_ATTRIBUTE_STATIC) {
+                               if (!(bflags & BFLAGS_Static))
+                                       continue;
+                               if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
+                                       continue;
+                       } else {
+                               if (!(bflags & BFLAGS_Instance))
+                                       continue;
+                       }
+               } else 
+                       if (!(bflags & BFLAGS_NonPublic))
                                continue;
-               }
-
+               
                g_free (event_name);
                return mono_event_get_object (domain, startklass, event);
        }
@@ -4133,6 +3868,8 @@ ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, Mon
        if (type->type->byref)
                return mono_array_new_cached (domain, System_Reflection_EventInfo, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+
 
 handle_parent: 
        if (klass->exception_type != MONO_EXCEPTION_NONE)
@@ -4202,10 +3939,15 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3
        
        MONO_ARCH_SAVE_REGS;
 
+       if (name == NULL)
+               mono_raise_exception (mono_get_exception_argument_null ("name"));
+       
        domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref)
                return NULL;
        klass = mono_class_from_mono_type (type->type);
+       mono_class_init_or_throw (klass);
+
        str = mono_string_to_utf8 (name);
 
  handle_parent:
@@ -4265,8 +4007,7 @@ 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));
+       mono_class_init_or_throw (klass);
 
        /*
         * If a nested type is generic, return its generic type definition.
@@ -4384,6 +4125,9 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                if (throwOnError)
                        e = mono_get_exception_type_load (name, NULL);
 
+               if (mono_loader_get_last_error () && mono_defaults.generic_ilist_class)
+                       e = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+
                mono_loader_clear_error ();
 
                if (e != NULL)
@@ -4464,7 +4208,7 @@ ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *asse
 
        replace_shadow_path (domain, dirname, &absolute);
        g_free (dirname);
-#if PLATFORM_WIN32
+#if HOST_WIN32
        {
                gint i;
                for (i = strlen (absolute) - 1; i >= 0; i--)
@@ -4476,7 +4220,7 @@ ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *asse
                uri = g_filename_to_uri (absolute, NULL, NULL);
        } else {
                const char *prepend = "file://";
-#if PLATFORM_WIN32
+#if HOST_WIN32
                if (*absolute == '/' && *(absolute + 1) == '/') {
                        prepend = "file:";
                } else {
@@ -4722,16 +4466,29 @@ ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *asse
        MonoImage *img = assembly->assembly->image;
        MonoArray *res;
        NameSpaceInfo info;
+       int len;
 
        MONO_ARCH_SAVE_REGS;
 
-       if (!img->name_cache)
-               mono_image_init_name_cache (img);
+       mono_image_lock (img);
+       mono_image_init_name_cache (img);
+
+RETRY_LEN:
+       len = g_hash_table_size (img->name_cache);
+       mono_image_unlock (img);
+
+       /*we can't create objects holding the image lock */
+       res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, len);
+
+       mono_image_lock (img);
+       /*len might have changed, create a new array*/
+       if (len != g_hash_table_size (img->name_cache))
+               goto RETRY_LEN;
 
-       res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
        info.res = res;
        info.idx = 0;
        g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
+       mono_image_unlock (img);
 
        return res;
 }
@@ -4792,7 +4549,7 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflection
        else
                module = assembly->assembly->image;
 
-       *ref_module = mono_module_get_object (mono_domain_get (), module);
+       mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) mono_module_get_object (mono_domain_get (), module));
 
        return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
 }
@@ -4972,7 +4729,8 @@ ves_icall_GetCurrentMethod (void)
 {
        MonoMethod *m = mono_method_get_last_managed ();
 
-       MONO_ARCH_SAVE_REGS;
+       while (m->is_inflated)
+               m = ((MonoMethodInflated*)m)->declaring;
 
        return mono_method_get_object (mono_domain_get (), m, NULL);
 }
@@ -4996,6 +4754,8 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
        }
 
        mono_class_setup_methods (method->klass);
+       if (method->klass->exception_type)
+               return NULL;
        for (i = 0; i < method->klass->method.count; ++i) {
                if (method->klass->methods [i] == method) {
                        offset = i;
@@ -5003,6 +4763,8 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
                }       
        }
        mono_class_setup_methods (klass);
+       if (klass->exception_type)
+               return NULL;
        g_assert (offset >= 0 && offset < klass->method.count);
        return klass->methods [offset];
 }
@@ -5015,8 +4777,11 @@ ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMeth
                klass = mono_class_from_mono_type (type);
                if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass)) 
                        return NULL;
-               if (method->klass != klass)
+               if (method->klass != klass) {
                        method = mono_method_get_equivalent_method (method, klass);
+                       if (!method)
+                               return NULL;
+               }
        } else
                klass = method->klass;
        return mono_method_get_object (mono_domain_get (), method, klass);
@@ -5085,7 +4850,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 :
@@ -5108,6 +4872,14 @@ ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full
        return res;
 }
 
+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);
+}
+
 static void
 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
 {
@@ -5139,7 +4911,7 @@ fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *a
 
                codebase = g_strdup (absolute);
 
-#if PLATFORM_WIN32
+#if HOST_WIN32
                {
                        gint i;
                        for (i = strlen (codebase) - 1; i >= 0; i--)
@@ -5239,14 +5011,14 @@ ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly,
        if (g_path_is_absolute (mass->image->name)) {
                fill_reflection_assembly_name (mono_object_domain (assembly),
                        aname, &mass->aname, mass->image->name, TRUE,
-                       TRUE, mono_framework_version () >= 2);
+                       TRUE, TRUE);
                return;
        }
        absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
 
        fill_reflection_assembly_name (mono_object_domain (assembly),
                aname, &mass->aname, absolute, TRUE, TRUE,
-               mono_framework_version () >= 2);
+               TRUE);
 
        g_free (absolute);
 }
@@ -5290,8 +5062,7 @@ ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname,
        }
 
        fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
-               TRUE, mono_framework_version () == 1,
-               mono_framework_version () >= 2);
+               TRUE, FALSE, TRUE);
 
        g_free (filename);
        mono_image_close (image);
@@ -5550,7 +5321,7 @@ ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module
 static gpointer
 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
 {
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        if (module->image && module->image->is_module_handle)
                return module->image->raw_data;
 #endif
@@ -5941,6 +5712,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)
 {
@@ -5949,7 +5734,13 @@ ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
        MONO_ARCH_SAVE_REGS;
 
        klass = mono_class_from_mono_type (type->type);
-       aklass = mono_array_class_get (klass, rank);
+       mono_class_init_or_throw (klass);
+       check_for_invalid_type (klass);
+
+       if (rank == 0) //single dimentional array
+               aklass = mono_array_class_get (klass, 1);
+       else
+               aklass = mono_bounded_array_class_get (klass, rank, TRUE);
 
        return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
 }
@@ -5962,6 +5753,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);
 }
@@ -5969,9 +5762,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);
 
@@ -5989,6 +5784,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) {
@@ -5998,10 +5795,7 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
 
        delegate = mono_object_new (mono_object_domain (type), delegate_class);
 
-       if (mono_method_needs_static_rgctx_invoke (method, FALSE)) {
-               method = mono_marshal_get_static_rgctx_invoke (method);
-               func = mono_compile_method (method);
-       } else if (method->dynamic) {
+       if (method->dynamic) {
                /* Creating a trampoline would leak memory */
                func = mono_compile_method (method);
        } else {
@@ -6032,7 +5826,7 @@ ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
  */
 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
 static void
 convert_to_absolute_date(SYSTEMTIME *date)
@@ -6062,7 +5856,7 @@ convert_to_absolute_date(SYSTEMTIME *date)
 }
 #endif
 
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
 /*
  * Return's the offset from GMT of a local time.
  * 
@@ -6102,7 +5896,7 @@ gmt_offset(struct tm *tm, time_t t)
 static guint32
 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
 {
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
        MonoDomain *domain = mono_domain_get ();
        struct tm start, tt;
        time_t t;
@@ -6116,8 +5910,8 @@ ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray
        MONO_CHECK_ARG_NULL (data);
        MONO_CHECK_ARG_NULL (names);
 
-       (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
-       (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+       mono_gc_wbarrier_generic_store (data, (MonoObject*) mono_array_new (domain, mono_defaults.int64_class, 4));
+       mono_gc_wbarrier_generic_store (names, (MonoObject*) mono_array_new (domain, mono_defaults.string_class, 2));
 
        /* 
         * no info is better than crashing: we'll need our own tz data
@@ -6215,8 +6009,8 @@ ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray
        MONO_CHECK_ARG_NULL (data);
        MONO_CHECK_ARG_NULL (names);
 
-       (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
-       (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+       mono_gc_wbarrier_generic_store (data, mono_array_new (domain, mono_defaults.int64_class, 4));
+       mono_gc_wbarrier_generic_store (names, mono_array_new (domain, mono_defaults.string_class, 2));
 
        for (i = 0; i < 32; ++i)
                if (!tz_info.DaylightName [i])
@@ -6406,7 +6200,7 @@ ves_icall_System_Environment_get_UserName (void)
 static MonoString *
 ves_icall_System_Environment_get_MachineName (void)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        gunichar2 *buf;
        guint32 len;
        MonoString *result;
@@ -6438,14 +6232,11 @@ ves_icall_System_Environment_get_MachineName (void)
 static int
 ves_icall_System_Environment_get_Platform (void)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (TARGET_WIN32)
        /* Win32NT */
        return 2;
 #elif defined(__MACH__)
        /* OSX */
-       if (mono_framework_version () < 2)
-               return 128;
-
        //
        // 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
@@ -6455,8 +6246,6 @@ ves_icall_System_Environment_get_Platform (void)
        return 4;
 #else
        /* Unix */
-       if (mono_framework_version () < 2)
-               return 128;
        return 4;
 #endif
 }
@@ -6466,7 +6255,7 @@ ves_icall_System_Environment_get_NewLine (void)
 {
        MONO_ARCH_SAVE_REGS;
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        return mono_string_new (mono_domain_get (), "\r\n");
 #else
        return mono_string_new (mono_domain_get (), "\n");
@@ -6505,7 +6294,7 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
  * arm-apple-darwin9.  We'll manually define the symbol on Apple as it does
  * in fact exist on all implementations (so far) 
  */
-gchar ***_NSGetEnviron();
+gchar ***_NSGetEnviron(void);
 #define environ (*_NSGetEnviron())
 #else
 extern
@@ -6517,7 +6306,7 @@ char **environ;
 static MonoArray *
 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
 {
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        MonoArray *names;
        MonoDomain *domain;
        MonoString *str;
@@ -6609,7 +6398,9 @@ ves_icall_System_Environment_GetEnvironmentVariableNames (void)
 static void
 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
 {
-#ifdef PLATFORM_WIN32
+       MonoError error;
+#ifdef HOST_WIN32
+
        gunichar2 *utf16_name, *utf16_value;
 #else
        gchar *utf8_name, *utf8_value;
@@ -6617,7 +6408,7 @@ ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, M
 
        MONO_ARCH_SAVE_REGS;
        
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        utf16_name = mono_string_to_utf16 (name);
        if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
                SetEnvironmentVariable (utf16_name, NULL);
@@ -6640,7 +6431,11 @@ ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, M
                return;
        }
 
-       utf8_value = mono_string_to_utf8 (value);
+       utf8_value = mono_string_to_utf8_checked (value, &error);
+       if (!mono_error_ok (&error)) {
+               g_free (utf8_name);
+               mono_error_raise_exception (&error);
+       }
        g_setenv (utf8_name, utf8_value, TRUE);
 
        g_free (utf8_name);
@@ -6657,6 +6452,9 @@ ves_icall_System_Environment_Exit (int result)
 
        mono_runtime_set_shutting_down ();
 
+       /* This will kill the tp threads which cannot be suspended */
+       mono_thread_pool_cleanup ();
+
        /* Suspend all managed threads since the runtime is going away */
        mono_thread_suspend_all_other_threads ();
 
@@ -6675,7 +6473,7 @@ ves_icall_System_Environment_GetGacPath (void)
 static MonoString*
 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        #ifndef CSIDL_FLAG_CREATE
                #define CSIDL_FLAG_CREATE       0x8000
        #endif
@@ -6848,7 +6646,7 @@ ves_icall_System_Environment_get_HasShutdownStarted (void)
 static void
 ves_icall_System_Environment_BroadcastSettingChange (void)
 {
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, NULL, L"Environment", SMTO_ABORTIFHUNG, 2000, 0);
 #endif
 }
@@ -6891,6 +6689,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;
@@ -6909,7 +6708,9 @@ ves_icall_Remoting_RemotingServices_GetVirtualMethod (
        vtable = klass->vtable;
 
        if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
-               int offs = mono_class_interface_offset (klass, method->klass);
+               gboolean variance_used = FALSE;
+               /*MS fails with variant interfaces but it's the right thing to do anyway.*/
+               int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
                if (offs >= 0)
                        res = vtable [offs + method->slot];
        } else {
@@ -6935,7 +6736,7 @@ ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (Mo
        MONO_ARCH_SAVE_REGS;
 
        klass = mono_class_from_mono_type (type->type);
-       vtable = mono_class_vtable (mono_domain_get (), klass);
+       vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE);
 
        if (enable) vtable->remote = 1;
        else vtable->remote = 0;
@@ -6951,13 +6752,14 @@ 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);
                return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
        } else {
                /* Bypass remoting object creation check */
-               return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
+               return mono_object_new_alloc_specific (mono_class_vtable_full (domain, klass, TRUE));
        }
 }
 
@@ -7027,7 +6829,7 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
 
        path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        /* Avoid mixing '/' and '\\' */
        {
                gint i;
@@ -7067,7 +6869,7 @@ ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
 
        path = g_path_get_dirname (mono_get_config_dir ());
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        /* Avoid mixing '/' and '\\' */
        {
                gint i;
@@ -7113,16 +6915,16 @@ ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result,
 static MonoBoolean
 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
 {
-       return mono_debug_using_mono_debugger ();
+       return mono_debug_using_mono_debugger () || mono_is_debugger_attached ();
 }
 
 static void
 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        OutputDebugString (mono_string_chars (message));
 #else
-       g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
+       g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
 #endif
 }
 
@@ -7137,6 +6939,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 */
@@ -7146,7 +6949,7 @@ ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
 }
 
 static MonoReflectionMethod *
-ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
+ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
 {
        MonoClass *klass, *parent;
        MonoMethod *method = m->method;
@@ -7166,13 +6969,19 @@ ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
 
-       /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
-       for (parent = klass->parent; parent != NULL; parent = parent->parent) {
-               mono_class_setup_vtable (parent);
-               if (parent->vtable_size <= method->slot)
-                       break;
-               klass = parent;
-       }               
+       if (definition) {
+               /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
+               for (parent = klass->parent; parent != NULL; parent = parent->parent) {
+                       mono_class_setup_vtable (parent);
+                       if (parent->vtable_size <= method->slot)
+                               break;
+                       klass = parent;
+               }
+       } else {
+               klass = klass->parent;
+               if (!klass)
+                       return m;
+       }
 
        if (klass == method->klass)
                return m;
@@ -7216,15 +7025,7 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
        if (start) {
                iter->args = start;
        } else {
-               guint32 i, arg_size;
-               gint32 align;
                iter->args = argsp + sizeof (gpointer);
-#ifndef MONO_ARCH_REGPARMS
-               for (i = 0; i < iter->sig->sentinelpos; ++i) {
-                       arg_size = mono_type_stack_size (iter->sig->params [i], &align);
-                       iter->args = (char*)iter->args + arg_size;
-               }
-#endif
        }
        iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
 
@@ -7363,6 +7164,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);
 }
@@ -7440,10 +7243,32 @@ static MonoArray*
 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
 {
        MonoType *type = param->ClassImpl->type;
-       MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
-       MonoImage *image = method->method->klass->image;
-       int pos = param->PositionImpl;
-       MonoMethodSignature *sig = mono_method_signature (method->method);
+       MonoClass *member_class = mono_object_class (param->MemberImpl);
+       MonoMethod *method = NULL;
+       MonoImage *image;
+       int pos;
+       MonoMethodSignature *sig;
+
+       if (mono_class_is_reflection_method_or_constructor (member_class)) {
+               MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
+               method = rmethod->method;
+       } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
+               MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
+               if (!(method = prop->property->get))
+                       method = prop->property->set;
+               g_assert (method);      
+       } else {
+               char *type_name = mono_type_get_full_name (member_class);
+               char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
+               MonoException *ex = mono_get_exception_not_supported  (msg);
+               g_free (type_name);
+               g_free (msg);
+               mono_raise_exception (ex);
+       }
+
+       image = method->klass->image;
+       pos = param->PositionImpl;
+       sig = mono_method_signature (method);
        if (pos == -1)
                type = sig->ret;
        else
@@ -7477,16 +7302,67 @@ property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean
        return type_array_from_modifiers (image, type, optional);
 }
 
+/*
+ *Construct a MonoType suited to be used to decode a constant blob object.
+ *
+ * @type is the target type which will be constructed
+ * @blob_type is the blob type, for example, that comes from the constant table
+ * @real_type is the expected constructed type.
+ */
+static void
+mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
+{
+       type->type = blob_type;
+       type->data.klass = NULL;
+       if (blob_type == MONO_TYPE_CLASS)
+               type->data.klass = mono_defaults.object_class;
+       else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
+               /* For enums, we need to use the base type */
+               type->type = MONO_TYPE_VALUETYPE;
+               type->data.klass = mono_class_from_mono_type (real_type);
+       } else
+               type->data.klass = mono_class_from_mono_type (real_type);
+}
+
+static MonoObject*
+property_info_get_default_value (MonoReflectionProperty *property)
+{
+       MonoType blob_type;
+       MonoProperty *prop = property->property;
+       MonoType *type = get_property_type (prop);
+       MonoDomain *domain = mono_object_domain (property); 
+       MonoTypeEnum def_type;
+       const char *def_value;
+       MonoObject *o;
+
+       g_assert (!prop->parent->image->dynamic);
+
+       mono_class_init (prop->parent);
+
+       if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT))
+               mono_raise_exception (mono_get_exception_invalid_operation (NULL));
+
+       def_value = mono_class_get_property_default_value (prop, &def_type);
+
+       mono_type_from_blob_type (&blob_type, def_type, type);
+       o = mono_get_object_from_blob (domain, &blob_type, def_value);
+
+       return o;
+}
+
 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;
@@ -7495,27 +7371,33 @@ 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;
+
+       if (attr_class)
+               mono_class_init_or_throw (attr_class);
+
+       res = mono_reflection_get_custom_attrs_by_type (obj, attr_class);
 
        if (mono_loader_get_last_error ()) {
                mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
                g_assert_not_reached ();
+               /* Not reached */
+               return NULL;
        } else {
                return res;
        }
 }
 
-static MonoBoolean
-GCHandle_CheckCurrentDomain (guint32 gchandle)
-{
-       return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
-}
-
 static MonoString*
 ves_icall_Mono_Runtime_GetDisplayName (void)
 {
-       static const char display_name_str [] = "Mono " VERSION;
-       MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
+       char *info;
+       MonoString *display_name;
+
+       info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
+       display_name = mono_string_new (mono_domain_get (), info);
+       g_free (info);
        return display_name;
 }
 
@@ -8089,7 +7971,7 @@ mono_create_icall_signature (const char *sigstr)
        res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
        res->pinvoke = 1;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        /* 
         * Under windows, the default pinvoke calling convention is STDCALL but
         * we need CDECL.