2007-10-04 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mono / metadata / icall.c
index 6119d5cd363430e6d79b41778e4c6336215d01ca..c3b45edd959bdb8213eeba6a010212413813e956 100644 (file)
 #include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 #if defined (PLATFORM_WIN32)
 #include <stdlib.h>
 #endif
@@ -39,6 +43,7 @@
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/gc-internal.h>
+#include <mono/metadata/mono-gc.h>
 #include <mono/metadata/rand.h>
 #include <mono/metadata/sysmath.h>
 #include <mono/metadata/string-icalls.h>
@@ -53,6 +58,7 @@
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/cil-coff.h>
 #include <mono/metadata/security-manager.h>
+#include <mono/metadata/security-core-clr.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/strtod.h>
 #include <mono/utils/monobitset.h>
@@ -65,6 +71,8 @@
 
 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
 
+static MonoArray*
+type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
 
 static inline MonoBoolean
 is_generic_parameter (MonoType *type)
@@ -88,7 +96,7 @@ mono_double_ParseImpl (char *ptr, double *result)
                *result = strtod (ptr, &endptr);
 #else
        if (*ptr)
-               *result = bsd_strtod (ptr, &endptr);
+               *result = mono_strtod (ptr, &endptr);
 #endif
 
        if (!*ptr || (endptr && *endptr))
@@ -115,14 +123,6 @@ mono_class_get_throw (MonoImage *image, guint32 type_token)
        return NULL;
 }
 
-static void
-ves_icall_System_Double_AssertEndianity (double *value)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       MONO_DOUBLE_ASSERT_ENDIANITY (value);
-}
-
 static MonoObject *
 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
 {
@@ -194,6 +194,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
        MonoClass *ac, *vc, *ec;
        gint32 esize, vsize;
        gpointer *ea, *va;
+       int et, vt;
 
        guint64 u64 = 0;
        gint64 i64 = 0;
@@ -282,8 +283,16 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
 
        vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
 
+       et = ec->byval_arg.type;
+       if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
+               et = ec->byval_arg.data.klass->enum_basetype->type;
+
+       vt = vc->byval_arg.type;
+       if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
+               vt = vc->byval_arg.data.klass->enum_basetype->type;
+
 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
-       switch (vc->byval_arg.type) { \
+       switch (vt) { \
        case MONO_TYPE_U1: \
        case MONO_TYPE_U2: \
        case MONO_TYPE_U4: \
@@ -305,7 +314,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
 }G_STMT_END
 
 #define ASSIGN_SIGNED(etype) G_STMT_START{\
-       switch (vc->byval_arg.type) { \
+       switch (vt) { \
        case MONO_TYPE_I1: \
        case MONO_TYPE_I2: \
        case MONO_TYPE_I4: \
@@ -331,7 +340,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
 }G_STMT_END
 
 #define ASSIGN_REAL(etype) G_STMT_START{\
-       switch (vc->byval_arg.type) { \
+       switch (vt) { \
        case MONO_TYPE_R4: \
        case MONO_TYPE_R8: \
                CHECK_WIDENING_CONVERSION(0); \
@@ -355,7 +364,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
        } \
 }G_STMT_END
 
-       switch (vc->byval_arg.type) {
+       switch (vt) {
        case MONO_TYPE_U1:
                u64 = *(guint8 *) va;
                break;
@@ -391,7 +400,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
                break;
        case MONO_TYPE_BOOLEAN:
                /* Boolean is only compatible with itself. */
-               switch (ec->byval_arg.type) {
+               switch (et) {
                case MONO_TYPE_CHAR:
                case MONO_TYPE_U1:
                case MONO_TYPE_U2:
@@ -411,7 +420,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
        }
 
        /* If we can't do a direct copy, let's try a widening conversion. */
-       switch (ec->byval_arg.type) {
+       switch (et) {
        case MONO_TYPE_CHAR:
                ASSIGN_UNSIGNED (guint16);
        case MONO_TYPE_U1:
@@ -686,31 +695,40 @@ ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpoin
 }
 
 static void
-ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
+ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
 {
-       MonoClass *klass = array->obj.vtable->klass;
-       guint32 size = mono_array_element_size (klass);
-       int i;
+       MonoClass *ac;
+       MonoArray *ao;
+       gint32 esize;
+       gpointer *ea;
 
        MONO_ARCH_SAVE_REGS;
 
-       if (array->bounds == NULL)
-               size *= array->max_length;
-       else
-               for (i = 0; i < klass->rank; ++i) 
-                       size *= array->bounds [i].length;
+       ao = (MonoArray *)this;
+       ac = (MonoClass *)ao->obj.vtable->klass;
 
-       memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
+       esize = mono_array_element_size (ac);
+       ea = (gpointer*)((char*)ao->vector + (pos * esize));
+
+       memcpy (ea, value, esize);
+}
+
+static void
+ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
+{
+       MonoClass *klass = array->obj.vtable->klass;
+       guint32 size = mono_array_element_size (klass);
+
+       size *= array->max_length;
 
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
 #define SWAP(n) {\
-       gint i; \
-       guint ## n tmp; \
        guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
+       guint ## n *src = (guint ## n *) field_handle->data; \
+       guint ## n *end = (guint ## n *)((char*)src + size); \
 \
-       for (i = 0; i < size; i += n/8, data++) { \
-               tmp = read ## n (data); \
-               *data = tmp; \
+       for (; src < end; data++, src++) { \
+               *data = read ## n (src); \
        } \
 }
 
@@ -724,14 +742,32 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoAr
                break;
        case MONO_TYPE_I4:
        case MONO_TYPE_U4:
+       case MONO_TYPE_R4:
                SWAP (32);
                break;
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
+       case MONO_TYPE_R8:
                SWAP (64);
                break;
+       default:
+               memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
+               break;
+       }
+#else
+       memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
+#ifdef ARM_FPU_FPA
+       if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
+               gint i;
+               double tmp;
+               double *data = (double*)mono_array_addr (array, double, 0);
+
+               for (i = 0; i < size; i++, data++) {
+                       readr8 (data, &tmp);
+                       *data = tmp;
+               }
        }
-                
+#endif
 #endif
 }
 
@@ -771,6 +807,18 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (Mo
                mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
 }
 
+static void
+ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       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));
+       }
+}
+
 static MonoObject *
 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
 {
@@ -1008,8 +1056,7 @@ type_from_name (const char *str, MonoBoolean ignoreCase)
 
        /* mono_reflection_parse_type() mangles the string */
        if (!mono_reflection_parse_type (temp_str, &info)) {
-               g_list_free (info.modifiers);
-               g_list_free (info.nested);
+               mono_reflection_free_type_info (&info);
                g_free (temp_str);
                return NULL;
        }
@@ -1045,8 +1092,7 @@ type_from_name (const char *str, MonoBoolean ignoreCase)
        if (!info.assembly.name && !type) /* try mscorlib */
                type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
 
-       g_list_free (info.modifiers);
-       g_list_free (info.nested);
+       mono_reflection_free_type_info (&info);
        g_free (temp_str);
 
        if (!type) 
@@ -1078,8 +1124,14 @@ ves_icall_type_from_name (MonoString *name,
        type = type_from_name (str, ignoreCase);
        g_free (str);
        if (type == NULL){
+               MonoException *e = NULL;
+               
                if (throwOnError)
-                       mono_raise_exception (mono_get_exception_type_load (name, NULL));
+                       e = mono_get_exception_type_load (name, NULL);
+
+               mono_loader_clear_error ();
+               if (e != NULL)
+                       mono_raise_exception (e);
        }
        
        return type;
@@ -1099,7 +1151,7 @@ ves_icall_type_from_handle (MonoType *handle)
 }
 
 static MonoBoolean
-ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
+ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
 {
        MONO_ARCH_SAVE_REGS;
 
@@ -1285,7 +1337,7 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *
        int i;
 
        if (klass->generic_container ||
-           (klass->generic_class && klass->generic_class->inst->is_open))
+           (klass->generic_class && klass->generic_class->context.class_inst->is_open))
                return NULL;
 
        info = mono_marshal_load_type_info (klass);
@@ -1302,6 +1354,20 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *
        return NULL;
 }
 
+static MonoReflectionField*
+ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
+{
+       g_assert (handle);
+
+       if (!klass)
+               klass = handle->parent;
+
+       /* 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)
 {
@@ -1312,6 +1378,14 @@ ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *hand
        return mono_field_get_object (mono_domain_get (), handle->parent, handle);
 }
 
+static MonoArray*
+ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
+{
+       MonoType *type = field->field->type;
+
+       return type_array_from_modifiers (field->field->parent->image, type, optional);
+}
+
 static void
 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
 {
@@ -1319,10 +1393,11 @@ ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
        MonoMethodSignature* sig;
        MONO_ARCH_SAVE_REGS;
 
-       if (method->is_inflated)
-               method = mono_get_inflated_method (method);
-
        sig = mono_method_signature (method);
+       if (!sig) {
+               g_assert (mono_loader_get_last_error ());
+               mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+       }
        
        info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
        info->ret = mono_type_get_object (domain, sig->ret);
@@ -1344,11 +1419,6 @@ ves_icall_get_parameter_info (MonoMethod *method)
 {
        MonoDomain *domain = mono_domain_get (); 
 
-       MONO_ARCH_SAVE_REGS;
-
-       if (method->is_inflated)
-               method = mono_get_inflated_method (method);
-
        return mono_param_get_objects (domain, method);
 }
 
@@ -1360,11 +1430,6 @@ ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
        MonoMarshalSpec **mspecs;
        int i;
 
-       MONO_ARCH_SAVE_REGS;
-
-       if (method->is_inflated)
-               method = mono_get_inflated_method (method);
-
        mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
        mono_method_get_marshal_info (method, mspecs);
 
@@ -1541,23 +1606,22 @@ ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *ob
                        break;
                case MONO_TYPE_GENERICINST: {
                        MonoGenericClass *gclass = cf->type->data.generic_class;
-                       g_assert (!gclass->inst->is_open);
+                       g_assert (!gclass->context.class_inst->is_open);
 
                        if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
                                MonoClass *nklass = mono_class_from_mono_type (cf->type);
-                               guint8 *buf;
+                               MonoObject *nullable;
 
                                /* 
                                 * Convert the boxed vtype into a Nullable structure.
                                 * This is complicated by the fact that Nullables have
                                 * a variable structure.
                                 */
-                               /* Allocate using alloca so it gets GC tracking */
-                               buf = alloca (nklass->instance_size);
+                               nullable = mono_object_new (mono_domain_get (), nklass);
 
-                               mono_nullable_init (buf, value, nklass);
+                               mono_nullable_init (mono_object_unbox (nullable), value, nklass);
 
-                               v = (gchar*)buf;
+                               v = mono_object_unbox (nullable);
                        }
                        else 
                                if (gclass->container_class->valuetype && (v != NULL))
@@ -1584,7 +1648,7 @@ ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *ob
 static MonoReflectionType*
 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
 {
-       MonoMethod *method = mono_get_inflated_method (rmethod->method.method);
+       MonoMethod *method = rmethod->method.method;
 
        return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
 }
@@ -1619,11 +1683,11 @@ ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo
 
        if ((req_info & PInfo_GetMethod) != 0)
                info->get = property->property->get ?
-                           mono_method_get_object (domain, property->property->get, NULL): NULL;
+                           mono_method_get_object (domain, property->property->get, property->klass): NULL;
        
        if ((req_info & PInfo_SetMethod) != 0)
                info->set = property->property->set ?
-                           mono_method_get_object (domain, property->property->set, NULL): NULL;
+                           mono_method_get_object (domain, property->property->set, property->klass): NULL;
        /* 
         * There may be other methods defined for properties, though, it seems they are not exposed 
         * in the reflection API 
@@ -1671,9 +1735,8 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type)
 
        MONO_ARCH_SAVE_REGS;
 
-       /* open generic-instance classes can share their interface_id */
-       if (class->generic_class && class->generic_class->inst->is_open) {
-               context = class->generic_class->context;
+       if (class->generic_class && class->generic_class->context.class_inst->is_open) {
+               context = mono_class_get_context (class);
                class = class->generic_class->container_class;
        }
 
@@ -1707,7 +1770,7 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type)
        for (i = 0; i < ifaces->len; ++i) {
                MonoClass *ic = g_ptr_array_index (ifaces, i);
                MonoType *ret = &ic->byval_arg;
-               if (context && ic->generic_class && ic->generic_class->inst->is_open)
+               if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
                        ret = mono_class_inflate_generic_type (ret, context);
                
                mono_array_setref (intf, i, mono_type_get_object (domain, ret));
@@ -1733,11 +1796,11 @@ ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType
        mono_class_setup_vtable (class);
 
        /* type doesn't implement iface: the exception is thrown in managed code */
-       if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
+       if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
                        return;
 
        len = mono_class_num_methods (iclass);
-       ioffset = class->interface_offsets [iclass->interface_id];
+       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);
@@ -1859,9 +1922,9 @@ 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->klass;
+               class = type->type->data.generic_param->owner->owner.klass;
        else if (type->type->type == MONO_TYPE_MVAR)
-               class = type->type->data.generic_param->method->klass;
+               class = type->type->data.generic_param->owner->owner.method->klass;
        else
                class = mono_class_from_mono_type (type->type)->nested_in;
 
@@ -1943,18 +2006,18 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
 
        if (klass->generic_container) {
                MonoGenericContainer *container = klass->generic_container;
-               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
+               res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
                for (i = 0; i < container->type_argc; ++i) {
                        pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
                        mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
                }
        } else if (klass->generic_class) {
-               MonoGenericInst *inst = klass->generic_class->inst;
-               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
+               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+               res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
                for (i = 0; i < inst->type_argc; ++i)
                        mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
        } else {
-               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
+               res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
        }
        return res;
 }
@@ -2014,6 +2077,7 @@ ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
        }
 
        geninst = mono_reflection_bind_generic_parameters (type, count, types);
+       g_free (types);
        if (!geninst)
                return NULL;
 
@@ -2145,7 +2209,7 @@ ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
                return NULL;
 
        inflated = mono_class_inflate_generic_type (
-               parent->type, gclass->generic_class.generic_class.context);
+               parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
 
        return mono_type_get_object (domain, inflated);
 }
@@ -2154,7 +2218,7 @@ static MonoArray*
 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
 {
        static MonoClass *System_Reflection_MonoGenericClass;
-       MonoDynamicGenericClass *gclass;
+       MonoGenericClass *gclass;
        MonoReflectionTypeBuilder *tb = NULL;
        MonoClass *klass = NULL;
        MonoDomain *domain;
@@ -2171,14 +2235,14 @@ ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
 
        domain = mono_object_domain (type);
 
-       g_assert (type->type.type->data.generic_class->is_dynamic);
-       gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
+       gclass = type->type.type->data.generic_class;
+       g_assert (gclass->is_dynamic);
 
        if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
                tb = (MonoReflectionTypeBuilder *) type->generic_type;
                icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
        } else {
-               klass = gclass->generic_class.generic_class.container_class;
+               klass = gclass->container_class;
                mono_class_init (klass);
                icount = klass->interface_count;
        }
@@ -2195,8 +2259,7 @@ ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
                } else
                        it = &klass->interfaces [i]->byval_arg;
 
-               it = mono_class_inflate_generic_type (
-                       it, gclass->generic_class.generic_class.context);
+               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);
@@ -2480,7 +2543,7 @@ ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
        if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
                return NULL;
 
-       method = type->type->data.generic_param->method;
+       method = type->type->data.generic_param->owner->owner.method;
        g_assert (method);
        klass = mono_class_from_mono_type (type->type);
        return mono_method_get_object (mono_object_domain (type), method, klass);
@@ -2558,16 +2621,16 @@ ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
 
        MONO_ARCH_SAVE_REGS;
 
-       if (!method->method->is_inflated) {
-               if (mono_method_signature (method->method)->generic_param_count)
-                       return method;
+       if (method->method->generic_container)
+               return method;
 
+       if (!method->method->is_inflated)
                return NULL;
-       }
 
        imethod = (MonoMethodInflated *) method->method;
-       if (imethod->context->gmethod && imethod->context->gmethod->reflection_info)
-               return imethod->context->gmethod->reflection_info;
+
+       if (imethod->reflection_info)
+               return imethod->reflection_info;
        else
                return mono_method_get_object (
                        mono_object_domain (method), imethod->declaring, NULL);
@@ -2586,8 +2649,7 @@ ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method
 {
        MONO_ARCH_SAVE_REGS;
 
-       return !method->method->is_inflated &&
-               (mono_method_signature (method->method)->generic_param_count != 0);
+       return method->method->generic_container != NULL;
 }
 
 static MonoArray*
@@ -2601,15 +2663,14 @@ ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
        domain = mono_object_domain (method);
 
        if (method->method->is_inflated) {
-               MonoMethodInflated *imethod = (MonoMethodInflated *) method->method;
-               MonoGenericMethod *gmethod = imethod->context->gmethod;
+               MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
 
-               if (gmethod) {
-                       count = gmethod->inst->type_argc;
+               if (inst) {
+                       count = inst->type_argc;
                        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, gmethod->inst->type_argv [i]));
+                               mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
 
                        return res;
                }
@@ -2629,6 +2690,35 @@ ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
        return res;
 }
 
+static void
+ensure_reflection_security (void)
+{
+       MonoMethod *m = mono_method_get_last_managed ();
+
+       while (m) {
+               /*
+               g_print ("method %s.%s.%s in image %s\n",
+                       m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
+               */
+
+               /* We stop at the first method which is not in
+                  System.Reflection or which is not in a platform
+                  image. */
+               if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
+                               !mono_security_core_clr_is_platform_image (m->klass->image)) {
+                       /* If the method is transparent we throw an exception. */
+                       if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
+                               MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
+
+                               mono_raise_exception (ex);
+                       }
+                       return;
+               }
+
+               mono_stack_walk_no_il (get_caller, &m);
+       }
+}
+
 static MonoObject *
 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) 
 {
@@ -2637,12 +2727,16 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
         * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
         * greater flexibility.
         */
-       MonoMethod *m = mono_get_inflated_method (method->method);
+       MonoMethod *m = method->method;
        int pcount;
        void *obj = this;
 
        MONO_ARCH_SAVE_REGS;
 
+       if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
+                       mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
+               ensure_reflection_security ();
+
        if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
                if (this) {
                        if (!mono_object_isinst (this, m->klass))
@@ -2659,7 +2753,7 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
        if (pcount != mono_method_signature (m)->param_count)
                mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
 
-       if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
+       if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
                mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
 
        if (m->klass->image->assembly->ref_only)
@@ -2743,7 +2837,8 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
                } else if (!strcmp (m->name, "FieldSetter")) {
                        MonoClass *k = this->vtable->klass;
                        MonoString *name;
-                       int size, align;
+                       guint32 size;
+                       gint32 align;
                        char *str;
                        
                        /* If this is a proxy, then it must be a CBO */
@@ -3035,9 +3130,15 @@ ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bfl
        compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
 
 handle_parent:
+       if (klass->exception_type != MONO_EXCEPTION_NONE)
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
        iter = NULL;
        while ((field = mono_class_get_fields (klass, &iter))) {
                match = 0;
+
+               if (field->type == NULL)
+                       continue;
                if (mono_field_is_deleted (field))
                        continue;
                if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
@@ -3101,6 +3202,9 @@ ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, Mon
        len = 2;
        res = mono_array_new (domain, mono_defaults.field_info_class, len);
 handle_parent: 
+       if (klass->exception_type != MONO_EXCEPTION_NONE)
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
        iter = NULL;
        while ((field = mono_class_get_fields (klass, &iter))) {
                match = 0;
@@ -3110,8 +3214,11 @@ handle_parent:
                        if (bflags & BFLAGS_Public)
                                match++;
                } else {
-                       if (bflags & BFLAGS_NonPublic)
-                               match++;
+                       if (bflags & BFLAGS_NonPublic) {
+                               /* Serialization currently depends on the old behavior.
+                                * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
+                                       match++;
+                       }
                }
                if (!match)
                        continue;
@@ -3181,7 +3288,10 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
 
        mono_class_setup_vtable (klass);
 
-       nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
+       if (is_generic_parameter (type->type))
+               nslots = klass->parent->vtable_size;
+       else
+               nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
        if (nslots >= sizeof (method_slots_default) * 8) {
                method_slots = g_new0 (guint32, nslots / 32 + 1);
        } else {
@@ -3193,6 +3303,9 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        res = mono_array_new (domain, mono_defaults.method_info_class, len);
 handle_parent:
        mono_class_setup_vtable (klass);
+       if (klass->exception_type != MONO_EXCEPTION_NONE)
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
        iter = NULL;
        while ((method = mono_class_get_methods (klass, &iter))) {
                match = 0;
@@ -3282,6 +3395,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);
 
+       if (klass->exception_type != MONO_EXCEPTION_NONE)
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
        if (!System_Reflection_ConstructorInfo)
                System_Reflection_ConstructorInfo = mono_class_from_name (
                        mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
@@ -3385,6 +3501,14 @@ ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name,
        res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
 handle_parent:
        mono_class_setup_vtable (klass);
+       if (klass->exception_type != MONO_EXCEPTION_NONE) {
+               if (method_slots != method_slots_default)
+                       g_free (method_slots);
+               if (name != NULL)
+                       g_free (propname);
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+       }
+
        iter = NULL;
        while ((prop = mono_class_get_properties (klass, &iter))) {
                match = 0;
@@ -3481,6 +3605,9 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32
        domain = mono_object_domain (type);
 
 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))
@@ -3542,6 +3669,9 @@ ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, Mon
        len = 2;
        res = mono_array_new (domain, System_Reflection_EventInfo, len);
 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))) {
                match = 0;
@@ -3608,7 +3738,7 @@ static MonoReflectionType *
 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
 {
        MonoDomain *domain; 
-       MonoClass *startklass, *klass;
+       MonoClass *klass;
        MonoClass *nested;
        GList *tmpn;
        char *str;
@@ -3618,10 +3748,25 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3
        domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref)
                return NULL;
-       klass = startklass = mono_class_from_mono_type (type->type);
+       klass = mono_class_from_mono_type (type->type);
        str = mono_string_to_utf8 (name);
 
  handle_parent:
+       if (klass->exception_type != MONO_EXCEPTION_NONE)
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
+       /*
+        * If a nested type is generic, return its generic type definition.
+        * Note that this means that the return value is essentially a
+        * nested type of the generic type definition of @klass.
+        *
+        * A note in MSDN claims that a generic type definition can have
+        * nested types that aren't generic.  In any case, the container of that
+        * nested type would be the generic type definition.
+        */
+       if (klass->generic_class)
+               klass = klass->generic_class->container_class;
+
        for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
                int match = 0;
                nested = tmpn->data;
@@ -3650,7 +3795,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
 {
        MonoDomain *domain; 
        GList *tmpn;
-       MonoClass *startklass, *klass;
+       MonoClass *klass;
        MonoArray *res;
        MonoObject *member;
        int i, len, match;
@@ -3661,7 +3806,21 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
        domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref)
                return mono_array_new (domain, mono_defaults.monotype_class, 0);
-       klass = startklass = mono_class_from_mono_type (type->type);
+       klass = mono_class_from_mono_type (type->type);
+       if (klass->exception_type != MONO_EXCEPTION_NONE)
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
+       /*
+        * If a nested type is generic, return its generic type definition.
+        * Note that this means that the return value is essentially the set
+        * of nested types of the generic type definition of @klass.
+        *
+        * A note in MSDN claims that a generic type definition can have
+        * nested types that aren't generic.  In any case, the container of that
+        * nested type would be the generic type definition.
+        */
+       if (klass->generic_class)
+               klass = klass->generic_class->container_class;
 
        i = 0;
        len = 1;
@@ -3716,8 +3875,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
        /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
        if (!mono_reflection_parse_type (str, &info)) {
                g_free (str);
-               g_list_free (info.modifiers);
-               g_list_free (info.nested);
+               mono_reflection_free_type_info (&info);
                if (throwOnError) /* uhm: this is a parse error, though... */
                        mono_raise_exception (mono_get_exception_type_load (name, NULL));
                /*g_print ("failed parse\n");*/
@@ -3758,12 +3916,18 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                else
                        type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
        g_free (str);
-       g_list_free (info.modifiers);
-       g_list_free (info.nested);
+       mono_reflection_free_type_info (&info);
        if (!type) {
+               MonoException *e = NULL;
+               
                if (throwOnError)
-                       mono_raise_exception (mono_get_exception_type_load (name, NULL));
-               /* g_print ("failed find\n"); */
+                       e = mono_get_exception_type_load (name, NULL);
+
+               mono_loader_clear_error ();
+
+               if (e != NULL)
+                       mono_raise_exception (e);
+
                return NULL;
        }
 
@@ -3773,6 +3937,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                if (throwOnError && klass->exception_type) {
                        /* report SecurityException (or others) that occured when loading the assembly */
                        MonoException *exc = mono_class_get_exception_for_failure (klass);
+                       mono_loader_clear_error ();
                        mono_raise_exception (exc);
                } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
                        return NULL;
@@ -3893,7 +4058,7 @@ ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *ass
 }
 
 static MonoReflectionModule*
-ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly) 
+ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly) 
 {
        return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
 }
@@ -4307,6 +4472,18 @@ ves_icall_GetCurrentMethod (void)
        return mono_method_get_object (mono_domain_get (), m, NULL);
 }
 
+static MonoReflectionMethod*
+ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
+{
+       /* FIXME check that method belongs to klass or a parent */
+       MonoClass *klass;
+       if (type)
+               klass = mono_class_from_mono_type (type);
+       else
+               klass = method->klass;
+       return mono_method_get_object (mono_domain_get (), method, klass);
+}
+
 static MonoReflectionMethod*
 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
 {
@@ -4378,8 +4555,10 @@ ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full
        if (!name)
                return NULL;
 
-       if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR))
+       if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
+               g_free (name);
                return NULL;
+       }
 
        res = mono_string_new (domain, name);
        g_free (name);
@@ -4489,7 +4668,10 @@ ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname,
                MonoException *exc;
 
                g_free (filename);
-               exc = mono_get_exception_file_not_found (fname);
+               if (status == MONO_IMAGE_IMAGE_INVALID)
+                       exc = mono_get_exception_bad_image_format2 (NULL, fname);
+               else
+                       exc = mono_get_exception_file_not_found2 (NULL, fname);
                mono_raise_exception (exc);
        }
 
@@ -4702,6 +4884,7 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
                list = NULL;
 
                exc = mono_get_exception_reflection_type_load (res, exl);
+               mono_loader_clear_error ();
                mono_raise_exception (exc);
        }
                
@@ -4780,13 +4963,8 @@ ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind,
 }
 
 static gint32
-ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module)
+ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
 {
-       MonoImage *image = module->image;
-
-       if (!image)
-               mono_raise_exception (mono_get_exception_not_supported (""));
-       
        return (image->md_version_major << 16) | (image->md_version_minor);
 }
 
@@ -4812,12 +4990,28 @@ mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
        return (*sig != 0x6);
 }
 
+static void
+init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
+{
+       if (type_args)
+               context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
+                                                                     mono_array_addr (type_args, MonoType*, 0));
+       else
+               context->class_inst = NULL;
+       if (method_args)
+               context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
+                                                                      mono_array_addr (method_args, MonoType*, 0));
+       else
+               context->method_inst = NULL;
+}
+
 static MonoType*
-ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
 {
        MonoClass *klass;
        int table = mono_metadata_token_table (token);
        int index = mono_metadata_token_index (token);
+       MonoGenericContext context;
 
        *error = ResolveTokenError_Other;
 
@@ -4828,15 +5022,20 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t
                return NULL;
        }
 
-       if (image->dynamic)
-               return mono_lookup_dynamic_token (image, token);
+       if (image->dynamic) {
+               if (type_args || method_args)
+                       mono_raise_exception (mono_get_exception_not_implemented (NULL));
+               return mono_lookup_dynamic_token (image, token, NULL);
+       }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
                *error = ResolveTokenError_OutOfRange;
                return NULL;
        }
 
-       klass = mono_class_get (image, token);
+       init_generic_context_from_args (&context, type_args, method_args);
+       klass = mono_class_get_full (image, token, &context);
+
        if (klass)
                return &klass->byval_arg;
        else
@@ -4844,10 +5043,12 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t
 }
 
 static MonoMethod*
-ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
 {
        int table = mono_metadata_token_table (token);
        int index = mono_metadata_token_index (token);
+       MonoGenericContext context;
+       MonoMethod *method;
 
        *error = ResolveTokenError_Other;
 
@@ -4858,9 +5059,12 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
                return NULL;
        }
 
-       if (image->dynamic)
+       if (image->dynamic) {
+               if (type_args || method_args)
+                       mono_raise_exception (mono_get_exception_not_implemented (NULL));
                /* FIXME: validate memberref token type */
-               return mono_lookup_dynamic_token (image, token);
+               return mono_lookup_dynamic_token (image, token, NULL);
+       }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
                *error = ResolveTokenError_OutOfRange;
@@ -4871,7 +5075,10 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
                return NULL;
        }
 
-       return mono_get_method (image, token, NULL);
+       init_generic_context_from_args (&context, type_args, method_args);
+       method = mono_get_method_full (image, token, NULL, &context);
+
+       return method;
 }
 
 static MonoString*
@@ -4888,7 +5095,7 @@ ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32
        }
 
        if (image->dynamic)
-               return mono_lookup_dynamic_token (image, token);
+               return mono_lookup_dynamic_token (image, token, NULL);
 
        if ((index <= 0) || (index >= image->heap_us.size)) {
                *error = ResolveTokenError_OutOfRange;
@@ -4901,11 +5108,13 @@ ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32
 }
 
 static MonoClassField*
-ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
 {
        MonoClass *klass;
        int table = mono_metadata_token_table (token);
        int index = mono_metadata_token_index (token);
+       MonoGenericContext context;
+       MonoClassField *field;
 
        *error = ResolveTokenError_Other;
 
@@ -4915,9 +5124,12 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32
                return NULL;
        }
 
-       if (image->dynamic)
+       if (image->dynamic) {
+               if (type_args || method_args)
+                       mono_raise_exception (mono_get_exception_not_implemented (NULL));
                /* FIXME: validate memberref token type */
-               return mono_lookup_dynamic_token (image, token);
+               return mono_lookup_dynamic_token (image, token, NULL);
+       }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
                *error = ResolveTokenError_OutOfRange;
@@ -4928,12 +5140,15 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32
                return NULL;
        }
 
-       return mono_field_from_token (image, token, &klass, NULL);
+       init_generic_context_from_args (&context, type_args, method_args);
+       field = mono_field_from_token (image, token, &klass, &context);
+       
+       return field;
 }
 
 
 static MonoObject*
-ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
 {
        int table = mono_metadata_token_table (token);
 
@@ -4943,7 +5158,7 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32
        case MONO_TABLE_TYPEDEF:
        case MONO_TABLE_TYPEREF:
        case MONO_TABLE_TYPESPEC: {
-               MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
+               MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
                if (t)
                        return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
                else
@@ -4951,14 +5166,14 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32
        }
        case MONO_TABLE_METHOD:
        case MONO_TABLE_METHODSPEC: {
-               MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
+               MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
                if (m)
                        return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
                else
                        return NULL;
        }               
        case MONO_TABLE_FIELD: {
-               MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
+               MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
                if (f)
                        return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
                else
@@ -4966,14 +5181,14 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32
        }
        case MONO_TABLE_MEMBERREF:
                if (mono_metadata_memberref_is_method (image, token)) {
-                       MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
+                       MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
                        if (m)
                                return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
                        else
                                return NULL;
                }
                else {
-                       MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
+                       MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
                        if (f)
                                return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
                        else
@@ -4988,6 +5203,38 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32
        return NULL;
 }
 
+static MonoArray*
+ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+{
+       int table = mono_metadata_token_table (token);
+       int idx = mono_metadata_token_index (token);
+       MonoTableInfo *tables = image->tables;
+       guint32 sig, len;
+       const char *ptr;
+       MonoArray *res;
+
+       *error = ResolveTokenError_OutOfRange;
+
+       /* FIXME: Support other tables ? */
+       if (table != MONO_TABLE_STANDALONESIG)
+               return NULL;
+
+       if (image->dynamic)
+               return NULL;
+
+       if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
+               return NULL;
+
+       sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
+
+       ptr = mono_metadata_blob_heap (image, sig);
+       len = mono_metadata_decode_blob_size (ptr, &ptr);
+
+       res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
+       memcpy (mono_array_addr (res, guint8, 0), ptr, len);
+       return res;
+}
+
 static MonoReflectionType*
 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
 {
@@ -5121,11 +5368,20 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
 }
 
 static void
-ves_icall_System_Delegate_FreeTrampoline (MonoDelegate *this)
+ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
 {
-       /*
-       Delegates have a finalizer only when needed, now.
-       mono_delegate_free_ftnptr (this);*/
+       gpointer iter;
+       MonoMethod *invoke;
+
+       /* Find the Invoke method */
+       iter = NULL;
+       while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) {
+               if (!strcmp (invoke->name, "Invoke"))
+                       break;
+       }
+       g_assert (invoke);
+
+       this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke));
 }
 
 /*
@@ -5605,9 +5861,11 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
  * There is no standard way to get at environ.
  */
 #ifndef _MSC_VER
+#ifndef __MINGW32_VERSION
 extern
-#endif
 char **environ;
+#endif
+#endif
 
 static MonoArray *
 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
@@ -5998,6 +6256,21 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
        return mcpath;
 }
 
+static MonoString *
+get_bundled_machine_config (void)
+{
+       const gchar *machine_config;
+
+       MONO_ARCH_SAVE_REGS;
+
+       machine_config = mono_get_machine_config ();
+
+       if (!machine_config)
+               return NULL;
+
+       return mono_string_new (mono_domain_get (), machine_config);
+}
+
 static MonoString *
 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
 {
@@ -6027,36 +6300,7 @@ static void
 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
 {
 #if defined (PLATFORM_WIN32)
-       static void (*output_debug) (gunichar2 *);
-       static gboolean tried_loading = FALSE;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (!tried_loading && output_debug == NULL) {
-               GModule *k32;
-
-               tried_loading = TRUE;
-               k32 = g_module_open ("kernel32", G_MODULE_BIND_LAZY);
-               if (!k32) {
-                       gchar *error = g_strdup (g_module_error ());
-                       g_warning ("Failed to load kernel32.dll: %s\n", error);
-                       g_free (error);
-                       return;
-               }
-
-               g_module_symbol (k32, "OutputDebugStringW", (gpointer *) &output_debug);
-               if (!output_debug) {
-                       gchar *error = g_strdup (g_module_error ());
-                       g_warning ("Failed to load OutputDebugStringW: %s\n", error);
-                       g_free (error);
-                       return;
-               }
-       }
-
-       if (output_debug == NULL)
-               return;
-       
-       output_debug (mono_string_chars (message));
+       OutputDebugString (mono_string_chars (message));
 #else
        g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
 #endif
@@ -6128,6 +6372,15 @@ ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
        return mono_method_get_object (mono_domain_get (), result, NULL);
 }
 
+static MonoString*
+ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
+{
+       MonoMethod *method = m->method;
+
+       MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
+       return m->name;
+}
+
 static void
 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
 {
@@ -6143,7 +6396,8 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
        if (start) {
                iter->args = start;
        } else {
-               int i, align, arg_size;
+               guint32 i, arg_size;
+               gint32 align;
                iter->args = argsp + sizeof (gpointer);
 #ifndef MONO_ARCH_REGPARMS
                for (i = 0; i < iter->sig->sentinelpos; ++i) {
@@ -6160,7 +6414,8 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
 static MonoTypedRef
 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
 {
-       gint i, align, arg_size;
+       guint32 i, arg_size;
+       gint32 align;
        MonoTypedRef res;
        MONO_ARCH_SAVE_REGS;
 
@@ -6184,7 +6439,8 @@ mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
 static MonoTypedRef
 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
 {
-       gint i, align, arg_size;
+       guint32 i, arg_size;
+       gint32 align;
        MonoTypedRef res;
        MONO_ARCH_SAVE_REGS;
 
@@ -6310,6 +6566,74 @@ ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
        return method->method->token;
 }
 
+/*
+ * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
+ * and avoid useless allocations.
+ */
+static MonoArray*
+type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
+{
+       MonoArray *res;
+       int i, count = 0;
+       for (i = 0; i < type->num_mods; ++i) {
+               if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
+                       count++;
+       }
+       if (!count)
+               return NULL;
+       res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
+       count = 0;
+       for (i = 0; i < type->num_mods; ++i) {
+               if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
+                       MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
+                       mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
+                       count++;
+               }
+       }
+       return res;
+}
+
+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);
+       if (pos == -1)
+               type = sig->ret;
+       else
+               type = sig->params [pos];
+
+       return type_array_from_modifiers (image, type, optional);
+}
+
+static MonoType*
+get_property_type (MonoProperty *prop)
+{
+       MonoMethodSignature *sig;
+       if (prop->get) {
+               sig = mono_method_signature (prop->get);
+               return sig->ret;
+       } else if (prop->set) {
+               sig = mono_method_signature (prop->set);
+               return sig->params [sig->param_count - 1];
+       }
+       return NULL;
+}
+
+static MonoArray*
+property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
+{
+       MonoType *type = get_property_type (property->property);
+       MonoImage *image = property->klass->image;
+
+       if (!type)
+               return NULL;
+       return type_array_from_modifiers (image, type, optional);
+}
+
 static MonoBoolean
 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
 {
@@ -6328,7 +6652,14 @@ custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
 static MonoArray*
 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
 {
-       return mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
+       MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
+
+       if (mono_loader_get_last_error ()) {
+               mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+               g_assert_not_reached ();
+       } else {
+               return res;
+       }
 }
 
 static MonoBoolean
@@ -6830,6 +7161,14 @@ type_from_typename (char *typename)
                klass = mono_defaults.int32_class;
        else if (!strcmp (typename, "uint32"))
                klass = mono_defaults.uint32_class;
+       else if (!strcmp (typename, "int8"))
+               klass = mono_defaults.sbyte_class;
+       else if (!strcmp (typename, "uint8"))
+               klass = mono_defaults.byte_class;
+       else if (!strcmp (typename, "int16"))
+               klass = mono_defaults.int16_class;
+       else if (!strcmp (typename, "uint16"))
+               klass = mono_defaults.uint16_class;
        else if (!strcmp (typename, "long"))
                klass = mono_defaults.int64_class;
        else if (!strcmp (typename, "ulong"))