2007-10-04 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mono / metadata / icall.c
index cf268860fa108f57732e33cf77b4c70a957d4fc8..c3b45edd959bdb8213eeba6a010212413813e956 100644 (file)
@@ -58,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>
@@ -70,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)
@@ -93,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))
@@ -691,6 +694,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)
 {
@@ -785,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)
 {
@@ -1022,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;
        }
@@ -1059,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) 
@@ -1346,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)
 {
@@ -1353,9 +1393,6 @@ 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 ());
@@ -1382,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);
 }
 
@@ -1398,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);
 
@@ -1583,19 +1610,18 @@ ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *ob
 
                        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))
@@ -1622,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);
 }
@@ -1657,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 
@@ -1980,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->context.class_inst;
-               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
+               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;
 }
@@ -2595,12 +2621,11 @@ 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;
 
@@ -2624,8 +2649,7 @@ ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method
 {
        MONO_ARCH_SAVE_REGS;
 
-       return method->method->generic_container &&
-               (mono_method_signature (method->method)->generic_param_count != 0);
+       return method->method->generic_container != NULL;
 }
 
 static MonoArray*
@@ -2666,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) 
 {
@@ -2674,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))
@@ -3073,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) {
@@ -3139,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;
@@ -3222,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 {
@@ -3234,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;
@@ -3323,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");
@@ -3426,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;
@@ -3522,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))
@@ -3583,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;
@@ -3663,6 +3752,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
@@ -3715,6 +3807,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.
@@ -3781,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");*/
@@ -3823,8 +3916,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;
                
@@ -3966,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);
 }
@@ -4463,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);
@@ -4896,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;
 
@@ -4912,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
@@ -4928,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;
 
@@ -4942,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;
@@ -4955,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*
@@ -4972,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;
@@ -4985,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;
 
@@ -4999,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;
@@ -5012,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);
 
@@ -5027,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
@@ -5035,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
@@ -5050,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
@@ -5072,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)
 {
@@ -6094,7 +6257,7 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
 }
 
 static MonoString *
-ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
+get_bundled_machine_config (void)
 {
        const gchar *machine_config;
 
@@ -6209,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)
 {
@@ -6395,7 +6567,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*