2007-09-11 Mark Probst <mark.probst@gmail.com>
[mono.git] / mono / metadata / icall.c
index cedc649af652e319e4b7342c67796c3164dd6850..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)
@@ -687,6 +693,25 @@ ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpoin
        memcpy (value, ea, esize);
 }
 
+static void
+ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
+{
+       MonoClass *ac;
+       MonoArray *ao;
+       gint32 esize;
+       gpointer *ea;
+
+       MONO_ARCH_SAVE_REGS;
+
+       ao = (MonoArray *)this;
+       ac = (MonoClass *)ao->obj.vtable->klass;
+
+       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)
 {
@@ -781,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)
 {
@@ -1018,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;
        }
@@ -1055,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) 
@@ -1301,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);
@@ -1318,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)
 {
@@ -1328,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)
 {
@@ -1335,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);
@@ -1360,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);
 }
 
@@ -1376,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);
 
@@ -1557,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))
@@ -1600,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);
 }
@@ -1687,8 +1734,7 @@ 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) {
+       if (class->generic_class && class->generic_class->context.class_inst->is_open) {
                context = mono_class_get_context (class);
                class = class->generic_class->container_class;
        }
@@ -1723,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));
@@ -1749,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);
@@ -1786,10 +1832,12 @@ ves_icall_MonoType_GetElementType (MonoReflectionType *type)
 
        MONO_ARCH_SAVE_REGS;
 
-       // GetElementType should only return a type for:
+       // GelElementType should only return a type for:
        // Array Pointer PassedByRef
        if (type->type->byref)
                return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
+       if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
+               return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
        else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
                return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
        else if (class->element_class && type->type->type == MONO_TYPE_PTR)
@@ -1963,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]));
@@ -2568,24 +2616,20 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
 static MonoReflectionMethod *
 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
 {
-       MonoGenericContext *context;
        MonoMethodInflated *imethod;
 
        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;
 
-       /* FIXME: should reflection_info be part of imethod? */
-       context = mono_method_get_context (method->method);
-       if (context->gmethod && context->gmethod->reflection_info)
-               return 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);
@@ -2604,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*
@@ -2619,14 +2662,14 @@ ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
        domain = mono_object_domain (method);
 
        if (method->method->is_inflated) {
-               MonoGenericMethod *gmethod = mono_method_get_context (method->method)->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;
                }
@@ -2654,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;
 
@@ -2676,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)
@@ -3053,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) {
@@ -3119,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;
@@ -3202,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 {
@@ -3214,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;
@@ -3303,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");
@@ -3406,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;
@@ -3502,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))
@@ -3563,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;
@@ -3643,6 +3718,9 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3
        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
@@ -3695,6 +3773,8 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
        if (type->type->byref)
                return mono_array_new (domain, mono_defaults.monotype_class, 0);
        klass = mono_class_from_mono_type (type->type);
+       if (klass->exception_type != MONO_EXCEPTION_NONE)
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
 
        /*
         * If a nested type is generic, return its generic type definition.
@@ -3761,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");*/
@@ -3803,8 +3882,7 @@ 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;
                
@@ -4360,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)
 {
@@ -4431,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);
@@ -4837,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);
 }
 
@@ -4869,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;
 
@@ -4885,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
@@ -4901,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;
 
@@ -4915,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;
@@ -4928,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*
@@ -4945,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;
@@ -4958,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;
 
@@ -4972,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;
@@ -4985,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);
 
@@ -5000,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
@@ -5008,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
@@ -5023,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
@@ -5045,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)
 {
@@ -5177,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.
@@ -5653,12 +5826,12 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
 /*
  * There is no standard way to get at environ.
  */
-#ifndef __MINGW32_VERSION
 #ifndef _MSC_VER
+#ifndef __MINGW32_VERSION
 extern
-#endif
 char **environ;
 #endif
+#endif
 
 static MonoArray *
 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
@@ -6165,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)
 {
@@ -6351,7 +6533,7 @@ ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
 }
 
 /*
- * We eturn NULL for no modifiers so the corlib code can return Type.EmptyTypes
+ * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
  * and avoid useless allocations.
  */
 static MonoArray*
@@ -6436,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