2007-09-11 Mark Probst <mark.probst@gmail.com>
[mono.git] / mono / metadata / icall.c
index 91e983bde0a86347971d9f5313c71a1d60758838..181a8da644abd0a7fe5724ea3aa4febcef8c55de 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
@@ -66,6 +70,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)
@@ -187,6 +193,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;
@@ -275,8 +282,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: \
@@ -298,7 +313,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: \
@@ -324,7 +339,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); \
@@ -348,7 +363,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;
@@ -384,7 +399,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:
@@ -404,7 +419,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:
@@ -679,31 +694,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); \
        } \
 }
 
@@ -717,14 +741,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
 }
 
@@ -764,6 +806,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)
 {
@@ -1001,8 +1055,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;
        }
@@ -1038,8 +1091,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) 
@@ -1071,8 +1123,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;
@@ -1092,7 +1150,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;
 
@@ -1278,7 +1336,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);
@@ -1295,6 +1353,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)
 {
@@ -1305,6 +1377,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)
 {
@@ -1312,10 +1392,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);
@@ -1337,11 +1418,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);
 }
 
@@ -1353,11 +1429,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);
 
@@ -1534,23 +1605,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))
@@ -1577,7 +1647,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);
 }
@@ -1664,9 +1734,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;
        }
 
@@ -1700,7 +1769,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));
@@ -1726,11 +1795,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);
@@ -1852,9 +1921,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;
 
@@ -1942,7 +2011,7 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
                        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;
+               MonoGenericInst *inst = klass->generic_class->context.class_inst;
                res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_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]));
@@ -2007,6 +2076,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;
 
@@ -2138,7 +2208,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);
 }
@@ -2147,7 +2217,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;
@@ -2164,14 +2234,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;
        }
@@ -2188,8 +2258,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);
@@ -2473,7 +2542,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);
@@ -2551,16 +2620,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);
@@ -2579,8 +2648,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*
@@ -2594,15 +2662,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;
                }
@@ -2630,7 +2697,7 @@ 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;
 
@@ -2652,7 +2719,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)
@@ -2736,7 +2803,8 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
                } else if (!strcmp (m->name, "FieldSetter")) {
                        MonoClass *k = this->vtable->klass;
                        MonoString *name;
-                       guint32 size, align;
+                       guint32 size;
+                       gint32 align;
                        char *str;
                        
                        /* If this is a proxy, then it must be a CBO */
@@ -3028,9 +3096,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) {
@@ -3094,6 +3168,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;
@@ -3104,7 +3181,8 @@ handle_parent:
                                match++;
                } else {
                        if (bflags & BFLAGS_NonPublic) {
-                               if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)
+                               /* Serialization currently depends on the old behavior.
+                                * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
                                        match++;
                        }
                }
@@ -3176,7 +3254,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 {
@@ -3188,6 +3269,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;
@@ -3277,6 +3361,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");
@@ -3380,6 +3467,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;
@@ -3476,6 +3571,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))
@@ -3537,6 +3635,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;
@@ -3603,7 +3704,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;
@@ -3613,10 +3714,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;
@@ -3645,7 +3761,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;
@@ -3656,7 +3772,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;
@@ -3711,8 +3841,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");*/
@@ -3753,12 +3882,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;
        }
 
@@ -3768,6 +3903,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;
@@ -4302,6 +4438,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)
 {
@@ -4373,8 +4521,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);
@@ -4700,6 +4850,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);
        }
                
@@ -4778,13 +4929,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);
 }
 
@@ -4810,12 +4956,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;
 
@@ -4826,15 +4988,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
@@ -4842,10 +5009,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;
 
@@ -4856,9 +5025,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;
@@ -4869,7 +5041,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*
@@ -4886,7 +5061,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;
@@ -4899,11 +5074,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;
 
@@ -4913,9 +5090,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;
@@ -4926,12 +5106,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);
 
@@ -4941,7 +5124,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
@@ -4949,14 +5132,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
@@ -4964,14 +5147,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
@@ -4986,6 +5169,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)
 {
@@ -5118,6 +5333,23 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
        return delegate;
 }
 
+static void
+ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *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));
+}
+
 /*
  * Magic number to convert a time which is relative to
  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
@@ -5595,9 +5827,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)
@@ -5988,6 +6222,21 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
        return mcpath;
 }
 
+static MonoString *
+ves_icall_System_Configuration_DefaultConfig_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)
 {
@@ -6089,6 +6338,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)
 {
@@ -6104,7 +6362,8 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
        if (start) {
                iter->args = start;
        } else {
-               guint32 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) {
@@ -6121,7 +6380,8 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
 static MonoTypedRef
 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
 {
-       guint32 i, align, arg_size;
+       guint32 i, arg_size;
+       gint32 align;
        MonoTypedRef res;
        MONO_ARCH_SAVE_REGS;
 
@@ -6145,7 +6405,8 @@ mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
 static MonoTypedRef
 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
 {
-       guint32 i, align, arg_size;
+       guint32 i, arg_size;
+       gint32 align;
        MonoTypedRef res;
        MONO_ARCH_SAVE_REGS;
 
@@ -6271,6 +6532,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)
 {
@@ -6289,7 +6618,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