2003-10-15 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / icall.c
index c9dec42b88026d5e00d1f983c7caf8a4071d9b90..bed4cb5072b7275f3fb919f54f006b3c362e51a0 100644 (file)
 #include <mono/metadata/rand.h>
 #include <mono/metadata/sysmath.h>
 #include <mono/metadata/string-icalls.h>
-#include <mono/metadata/debug-mono-symfile.h>
+#include <mono/metadata/mono-debug-debugger.h>
 #include <mono/metadata/process.h>
 #include <mono/metadata/environment.h>
 #include <mono/metadata/profiler-private.h>
+#include <mono/metadata/locales.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/strtod.h>
 
@@ -74,6 +75,14 @@ mono_double_ParseImpl (char *ptr)
        return result;
 }
 
+static void
+ves_icall_System_Double_AssertEndianity (double *value)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       MONO_DOUBLE_ASSERT_ENDIANITY (value);
+}
+
 static MonoObject *
 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
 {
@@ -217,6 +226,8 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
        }
 
        if (!ec->valuetype) {
+               if (!mono_object_isinst (value, ec))
+                       INVALID_CAST;
                *ea = (gpointer)value;
                return;
        }
@@ -464,7 +475,7 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *
                if (mono_array_get (lengths, gint32, i) < 0)
                        mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
 
-       aklass = mono_array_class_get (type->type, mono_array_length (lengths));
+       aklass = mono_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths));
 
        sizes = alloca (aklass->rank * sizeof(guint32) * 2);
        for (i = 0; i < aklass->rank; ++i) {
@@ -678,7 +689,7 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (Mo
 
        /* This will call the type constructor */
        if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
-               mono_class_vtable (mono_domain_get (), klass);
+               mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
 }
 
 static MonoObject *
@@ -835,7 +846,7 @@ ves_icall_type_from_name (MonoString *name,
                g_list_free (info.modifiers);
                g_list_free (info.nested);
                if (throwOnError) /* uhm: this is a parse error, though... */
-                       mono_raise_exception (mono_get_exception_type_load ());
+                       mono_raise_exception (mono_get_exception_type_load (name));
 
                return NULL;
        }
@@ -860,7 +871,7 @@ ves_icall_type_from_name (MonoString *name,
        g_list_free (info.nested);
        if (!type) {
                if (throwOnError)
-                       mono_raise_exception (mono_get_exception_type_load ());
+                       mono_raise_exception (mono_get_exception_type_load (name));
 
                return NULL;
        }
@@ -963,11 +974,8 @@ handle_enum:
                                        return TYPECODE_DECIMAL;
                                else if (strcmp (k->name, "DateTime") == 0)
                                        return TYPECODE_DATETIME;
-                               else if (strcmp (k->name, "DBNull") == 0)
-                                       return TYPECODE_DBNULL;
                        }
                }
-               /* handle datetime, dbnull.. */
                return TYPECODE_OBJECT;
        case MONO_TYPE_STRING:
                return TYPECODE_STRING;
@@ -976,6 +984,13 @@ handle_enum:
        case MONO_TYPE_OBJECT:
                return TYPECODE_OBJECT;
        case MONO_TYPE_CLASS:
+               {
+                       MonoClass *k =  type->type->data.klass;
+                       if (strcmp (k->name_space, "System") == 0) {
+                               if (strcmp (k->name, "DBNull") == 0)
+                                       return TYPECODE_DBNULL;
+                       }
+               }
                return TYPECODE_OBJECT;
        default:
                g_error ("type 0x%02x not handled in GetTypeCode()", t);
@@ -1005,6 +1020,25 @@ ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, M
        return mono_class_is_subclass_of (klass, klassc, check_interfaces);
 }
 
+static guint32
+ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
+{
+       MonoDomain *domain; 
+       MonoClass *klass;
+       MonoClass *klassc;
+
+       MONO_ARCH_SAVE_REGS;
+
+       g_assert (type != NULL);
+       
+       domain = ((MonoObject *)type)->vtable->domain;
+
+       klass = mono_class_from_mono_type (type->type);
+       klassc = mono_class_from_mono_type (c->type);
+
+       return mono_class_is_assignable_from (klass, klassc);
+}
+
 static guint32
 ves_icall_get_attributes (MonoReflectionType *type)
 {
@@ -1015,16 +1049,14 @@ ves_icall_get_attributes (MonoReflectionType *type)
        return klass->flags;
 }
 
-static MonoFieldInfo*
+static MonoReflectionField*
 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
 {
        MONO_ARCH_SAVE_REGS;
 
        g_assert (handle);
 
-       return (MonoFieldInfo*) mono_field_get_object (mono_domain_get (), 
-                                                                                                  handle->parent,
-                                                                                                  handle);
+       return mono_field_get_object (mono_domain_get (), handle->parent, handle);
 }
 
 static void
@@ -1044,35 +1076,21 @@ static MonoArray*
 ves_icall_get_parameter_info (MonoMethod *method)
 {
        MonoDomain *domain = mono_domain_get (); 
-       MonoArray *res;
-       static MonoClass *System_Reflection_ParameterInfo;
-       MonoReflectionParameter** args;
-       int i;
 
        MONO_ARCH_SAVE_REGS;
 
-       args = mono_param_get_objects (domain, method);
-       if (!System_Reflection_ParameterInfo)
-               System_Reflection_ParameterInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "ParameterInfo");
-       res = mono_array_new (domain, System_Reflection_ParameterInfo, method->signature->param_count);
-       for (i = 0; i < method->signature->param_count; ++i) {
-               mono_array_set (res, gpointer, i, args [i]);
-       }
-       return res;
+       return mono_param_get_objects (domain, method);
 }
 
-static void
-ves_icall_get_field_info (MonoReflectionField *field, MonoFieldInfo *info)
+static MonoReflectionType*
+ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
 {
-       MonoDomain *domain = mono_object_domain (field); 
-
+       MonoClass *parent;
        MONO_ARCH_SAVE_REGS;
 
-       info->parent = mono_type_get_object (domain, &field->klass->byval_arg);
-       info->type = mono_type_get_object (domain, field->field->type);
-       info->name = mono_string_new (domain, field->field->name);
-       info->attrs = field->field->type->attrs;
+       parent = declaring? field->field->parent: field->klass;
+
+       return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
 }
 
 static MonoObject *
@@ -1125,6 +1143,8 @@ ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *ob
        if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
                is_static = TRUE;
                vtable = mono_class_vtable (domain, field->klass);
+               if (!vtable->initialized)
+                       mono_runtime_class_init (vtable);
        }
        
        if (is_ref) {
@@ -1193,6 +1213,8 @@ ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *ob
 
        if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
                MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), field->klass);
+               if (!vtable->initialized)
+                       mono_runtime_class_init (vtable);
                mono_field_static_set_value (vtable, cf, v);
        } else {
                mono_field_set_value (obj, cf, v);
@@ -1243,6 +1265,11 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type)
 
        MONO_ARCH_SAVE_REGS;
 
+       if (class->rank) {
+               /* GetInterfaces() returns an empty array in MS.NET (this may be a bug) */
+               return mono_array_new (domain, mono_defaults.monotype_class, 0);
+       }
+
        ninterf = 0;
        for (parent = class; parent; parent = parent->parent) {
                ninterf += parent->interface_count;
@@ -1293,6 +1320,8 @@ ves_icall_MonoType_GetElementType (MonoReflectionType *type)
 
        MONO_ARCH_SAVE_REGS;
 
+       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)
@@ -1319,6 +1348,14 @@ ves_icall_type_ispointer (MonoReflectionType *type)
        return type->type->type == MONO_TYPE_PTR;
 }
 
+static MonoBoolean
+ves_icall_type_isprimitive (MonoReflectionType *type)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       return (!type->type->byref && (type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8));
+}
+
 static MonoBoolean
 ves_icall_type_isbyref (MonoReflectionType *type)
 {
@@ -1360,6 +1397,191 @@ ves_icall_get_type_info (MonoType *type, MonoTypeInfo *info)
        info->isprimitive = (!type->byref && (type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8));
 }
 
+static MonoArray*
+ves_icall_Type_GetGenericArguments (MonoReflectionType *type)
+{
+       MonoArray *res;
+       MonoClass *klass, *pklass;
+       int i;
+       MONO_ARCH_SAVE_REGS;
+
+       klass = mono_class_from_mono_type (type->type);
+
+       if (type->type->byref) {
+               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
+       } else if (klass->gen_params) {
+               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, klass->num_gen_params);
+               for (i = 0; i < klass->num_gen_params; ++i) {
+                       pklass = mono_class_from_generic_parameter (&klass->gen_params [i], klass->image, FALSE);
+                       mono_array_set (res, gpointer, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
+               }
+       } else if (klass->generic_inst) {
+               MonoGenericInst *inst = klass->generic_inst->data.generic_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_set (res, gpointer, 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);
+       }
+       return res;
+}
+
+static gboolean
+ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
+{
+       MonoClass *klass;
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return FALSE;
+       klass = mono_class_from_mono_type (type->type);
+
+       return klass->gen_params != NULL;
+}
+
+static MonoReflectionType*
+ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
+{
+       MonoClass *klass;
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return NULL;
+       klass = mono_class_from_mono_type (type->type);
+       if (klass->gen_params) {
+               return type; /* check this one */
+       }
+       if (klass->generic_inst) {
+               MonoType *generic_type = klass->generic_inst->data.generic_inst->generic_type;
+               MonoClass *generic_class = mono_class_from_mono_type (generic_type);
+
+               if (generic_class->wastypebuilder && generic_class->reflection_info)
+                       return generic_class->reflection_info;
+               else
+                       return mono_type_get_object (mono_object_domain (type), generic_type);
+       }
+       return NULL;
+}
+
+static MonoReflectionType*
+ves_icall_Type_BindGenericParameters (MonoReflectionType *type, MonoArray *types)
+{
+       MonoClass *klass;
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return NULL;
+
+       klass = mono_reflection_bind_generic_parameters (type, types);
+
+       return mono_type_get_object (mono_object_domain (type), klass->generic_inst);
+}
+
+static gboolean
+ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
+{
+       MonoClass *klass;
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return FALSE;
+       klass = mono_class_from_mono_type (type->type);
+       return klass->generic_inst != NULL;
+}
+
+static gint32
+ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return -1;
+       if (type->type->type == MONO_TYPE_VAR || type->type->type == MONO_TYPE_MVAR)
+               return type->type->data.generic_param->num;
+       return -1;
+}
+
+static MonoBoolean
+ves_icall_MonoType_get_HasGenericArguments (MonoReflectionType *type)
+{
+       MonoClass *klass;
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return FALSE;
+       klass = mono_class_from_mono_type (type->type);
+       if (klass->gen_params || klass->generic_inst)
+               return TRUE;
+       return FALSE;
+}
+
+static MonoBoolean
+ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return FALSE;
+       if (type->type->type == MONO_TYPE_VAR || type->type->type == MONO_TYPE_MVAR)
+               return TRUE;
+       return FALSE;
+}
+
+static MonoBoolean
+ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       if (tb->type.type->byref)
+               return FALSE;
+       if (tb->type.type->type == MONO_TYPE_VAR || tb->type.type->type == MONO_TYPE_MVAR)
+               return TRUE;
+       return FALSE;
+}
+
+static MonoReflectionType*
+ves_icall_TypeBuilder_define_generic_parameter (MonoReflectionTypeBuilder *tb, MonoReflectionGenericParam *gparam)
+{
+       guint32 index;
+
+       MONO_ARCH_SAVE_REGS;
+
+       index = mono_array_length (tb->generic_params) - 1;
+       return mono_reflection_define_generic_parameter (tb, NULL, index, gparam);
+}
+
+static MonoReflectionType*
+ves_icall_MethodBuilder_define_generic_parameter (MonoReflectionMethodBuilder *mb, MonoReflectionGenericParam *gparam)
+{
+       guint32 index;
+
+       MONO_ARCH_SAVE_REGS;
+
+       index = mono_array_length (mb->generic_params) - 1;
+       return mono_reflection_define_generic_parameter (NULL, mb, index, gparam);
+}
+
+static MonoReflectionMethod *
+ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
+{
+       MonoMethod *method;
+       MonoClass *klass;
+
+       MONO_ARCH_SAVE_REGS;
+
+       if (type->type->byref)
+               return FALSE;
+
+       method = type->type->data.generic_param->method;
+       if (!method)
+               return NULL;
+
+       klass = mono_class_from_mono_type (type->type);
+       return mono_method_get_object (mono_object_domain (type), method, klass);
+}
+
+
 static MonoObject *
 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) 
 {
@@ -1377,13 +1599,34 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
                if (!mono_object_isinst (this, m->klass))
                        mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
                m = mono_object_get_virtual_method (this, m);
-       } else if (!(m->flags & METHOD_ATTRIBUTE_STATIC) && strcmp (m->name, ".ctor"))
+       } else if (!(m->flags & METHOD_ATTRIBUTE_STATIC) && strcmp (m->name, ".ctor") && !m->wrapper_type)
                mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
 
        pcount = params? mono_array_length (params): 0;
        if (pcount != m->signature->param_count)
                mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
 
+       if (m->klass->rank && !strcmp (m->name, ".ctor")) {
+               int i;
+               guint32 *lengths;
+               guint32 *lower_bounds;
+               pcount = mono_array_length (params);
+               lengths = alloca (sizeof (guint32) * pcount);
+               for (i = 0; i < pcount; ++i)
+                       lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
+
+               if (m->klass->rank == pcount) {
+                       /* Only lengths provided. */
+                       lower_bounds = NULL;
+               } else {
+                       g_assert (pcount == (m->klass->rank * 2));
+                       /* lower bounds are first. */
+                       lower_bounds = lengths;
+                       lengths += m->klass->rank;
+               }
+
+               return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
+       }
        return mono_runtime_invoke_array (m, this, params, NULL);
 }
 
@@ -1622,7 +1865,7 @@ enum {
        BFLAGS_OptionalParamBinding = 0x40000
 };
 
-static MonoFieldInfo *
+static MonoReflectionField *
 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
 {
        MonoDomain *domain; 
@@ -1636,7 +1879,7 @@ ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bfl
        MONO_ARCH_SAVE_REGS;
 
        if (!name)
-               return NULL;
+               mono_raise_exception (mono_get_exception_argument_null ("name"));
 
 handle_parent: 
        for (i = 0; i < klass->field.count; ++i) {
@@ -1671,7 +1914,7 @@ handle_parent:
                }
                g_free (utf8_name);
                
-               return (MonoFieldInfo *)mono_field_get_object (domain, klass, field);
+               return mono_field_get_object (domain, klass, field);
        }
        if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto handle_parent;
@@ -1727,7 +1970,7 @@ handle_parent:
        len = g_slist_length (l);
        res = mono_array_new (domain, mono_defaults.field_info_class, len);
        i = 0;
-       tmp = g_slist_reverse (l);
+       tmp = l = g_slist_reverse (l);
        for (; tmp; tmp = tmp->next, ++i)
                mono_array_set (res, gpointer, i, tmp->data);
        g_slist_free (l);
@@ -1791,7 +2034,9 @@ handle_parent:
                goto handle_parent;
        res = mono_array_new (domain, mono_defaults.method_info_class, len);
        i = 0;
-       tmp = l;
+
+       tmp = l = g_slist_reverse (l);
+
        for (; tmp; tmp = tmp->next, ++i)
                mono_array_set (res, gpointer, i, tmp->data);
        g_slist_free (l);
@@ -1851,7 +2096,7 @@ ves_icall_Type_GetConstructors (MonoReflectionType *type, guint32 bflags)
                        mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
        res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
        i = 0;
-       tmp = g_slist_reverse (l);
+       tmp = l = g_slist_reverse (l);
        for (; tmp; tmp = tmp->next, ++i)
                mono_array_set (res, gpointer, i, tmp->data);
        g_slist_free (l);
@@ -1920,7 +2165,9 @@ handle_parent:
                        mono_defaults.corlib, "System.Reflection", "PropertyInfo");
        res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
        i = 0;
-       tmp = l;
+
+       tmp = l = g_slist_reverse (l);
+
        for (; tmp; tmp = tmp->next, ++i)
                mono_array_set (res, gpointer, i, tmp->data);
        g_slist_free (l);
@@ -2028,13 +2275,54 @@ handle_parent:
                        mono_defaults.corlib, "System.Reflection", "EventInfo");
        res = mono_array_new (domain, System_Reflection_EventInfo, len);
        i = 0;
-       tmp = l;
+
+       tmp = l = g_slist_reverse (l);
+
        for (; tmp; tmp = tmp->next, ++i)
                mono_array_set (res, gpointer, i, tmp->data);
        g_slist_free (l);
        return res;
 }
 
+static MonoReflectionType *
+ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
+{
+       MonoDomain *domain; 
+       MonoClass *startklass, *klass;
+       MonoClass *nested;
+       GList *tmpn;
+       char *str;
+       
+       MONO_ARCH_SAVE_REGS;
+
+       domain = ((MonoObject *)type)->vtable->domain;
+       klass = startklass = mono_class_from_mono_type (type->type);
+       str = mono_string_to_utf8 (name);
+
+ handle_parent:
+       for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
+               int match = 0;
+               nested = tmpn->data;
+               if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
+                       if (bflags & BFLAGS_Public)
+                               match++;
+               } else {
+                       if (bflags & BFLAGS_NonPublic)
+                               match++;
+               }
+               if (!match)
+                       continue;
+               if (strcmp (nested->name, str) == 0){
+                       g_free (str);
+                       return mono_type_get_object (domain, &nested->byval_arg);
+               }
+       }
+       if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
+               goto handle_parent;
+       g_free (str);
+       return NULL;
+}
+
 static MonoArray*
 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
 {
@@ -2070,7 +2358,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
        len = g_slist_length (l);
        res = mono_array_new (domain, mono_defaults.monotype_class, len);
        i = 0;
-       tmp = g_slist_reverse (l);
+       tmp = l = g_slist_reverse (l);
        for (; tmp; tmp = tmp->next, ++i)
                mono_array_set (res, gpointer, i, tmp->data);
        g_slist_free (l);
@@ -2093,7 +2381,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                g_list_free (info.modifiers);
                g_list_free (info.nested);
                if (throwOnError) /* uhm: this is a parse error, though... */
-                       mono_raise_exception (mono_get_exception_type_load ());
+                       mono_raise_exception (mono_get_exception_type_load (name));
                /*g_print ("failed parse\n");*/
                return NULL;
        }
@@ -2104,7 +2392,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
        g_list_free (info.nested);
        if (!type) {
                if (throwOnError)
-                       mono_raise_exception (mono_get_exception_type_load ());
+                       mono_raise_exception (mono_get_exception_type_load (name));
                /* g_print ("failed find\n"); */
                return NULL;
        }
@@ -2148,6 +2436,16 @@ ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assem
        return res;
 }
 
+static MonoString *
+ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
+{
+       MonoDomain *domain = mono_object_domain (assembly); 
+
+       MONO_ARCH_SAVE_REGS;
+
+       return mono_string_new (domain, assembly->assembly->image->version);
+}
+
 static MonoReflectionMethod*
 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly) 
 {
@@ -2200,7 +2498,7 @@ ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAsse
        for (i = 0; i < count; i++) {
                MonoAssembly *assem = assembly->assembly->image->references [i];
                MonoReflectionAssemblyName *aname;
-               char *codebase;
+               char *codebase, *absolute;
 
                aname = (MonoReflectionAssemblyName *) mono_object_new (
                        domain, System_Reflection_AssemblyName);
@@ -2211,14 +2509,48 @@ ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAsse
                        aname->name = mono_string_new (domain, assem->aname.name);
                aname->major = assem->aname.major;
 
-               codebase = g_filename_to_uri (assembly->assembly->image->references [i]->image->name, NULL, NULL);
+               absolute = g_build_filename (assem->basedir, assem->image->module_name, NULL);
+               codebase = g_filename_to_uri (absolute, NULL, NULL);
                aname->codebase = mono_string_new (domain, codebase);
                g_free (codebase);
+               g_free (absolute);
                mono_array_set (result, gpointer, i, aname);
        }
        return result;
 }
 
+typedef struct {
+       MonoArray *res;
+       int idx;
+} NameSpaceInfo;
+
+static void
+foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
+{
+       MonoString *name = mono_string_new (mono_object_domain (info->res), key);
+
+       mono_array_set (info->res, gpointer, info->idx, name);
+       info->idx++;
+}
+
+static MonoArray*
+ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly) 
+{
+       MonoImage *img = assembly->assembly->image;
+       int n;
+       MonoArray *res;
+       NameSpaceInfo info;
+       
+       MONO_ARCH_SAVE_REGS;
+
+       n = g_hash_table_size (img->name_cache);
+       res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, n);
+       info.res = res;
+       info.idx = 0;
+       g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
+       return res;
+}
+
 /* move this in some file in mono/util/ */
 static char *
 g_concat_dir_and_file (const char *dir, const char *file)
@@ -2236,15 +2568,14 @@ g_concat_dir_and_file (const char *dir, const char *file)
                return g_strconcat (dir, file, NULL);
 }
 
-static MonoObject*
-ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name) 
+static void *
+ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size
 {
        char *n = mono_string_to_utf8 (name);
        MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
        guint32 i;
        guint32 cols [MONO_MANIFEST_SIZE];
        const char *val;
-       MonoObject *result;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -2258,33 +2589,74 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflection
        if (i == table->rows)
                return NULL;
        /* FIXME */
+       if (cols [MONO_MANIFEST_IMPLEMENTATION]) {
+               /*
+                * this code should only be called after obtaining the 
+                * ResourceInfo and handling the other cases.
+                */
+               g_assert_not_reached ();
+               return NULL;
+       }
+
+       return (void*)mono_image_get_resource (assembly->assembly->image, cols [MONO_MANIFEST_OFFSET], size);
+}
+
+static gboolean
+ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
+{
+       MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
+       int i;
+       guint32 cols [MONO_MANIFEST_SIZE];
+       guint32 file_cols [MONO_FILE_SIZE];
+       const char *val;
+       char *n;
+
+       MONO_ARCH_SAVE_REGS;
+
+       n = mono_string_to_utf8 (name);
+       for (i = 0; i < table->rows; ++i) {
+               mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
+               val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
+               if (strcmp (val, n) == 0)
+                       break;
+       }
+       g_free (n);
+       if (i == table->rows)
+               return FALSE;
+
        if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
-               guint32 size;
-               MonoArray *data;
-               val = mono_image_get_resource (assembly->assembly->image, cols [MONO_MANIFEST_OFFSET], &size);
-               if (!val)
-                       return NULL;
-               data = mono_array_new (mono_object_domain (assembly), mono_defaults.byte_class, size);
-               memcpy (mono_array_addr (data, char, 0), val, size);
-               return (MonoObject*)data;
-       }
-       switch (cols [MONO_MANIFEST_IMPLEMENTATION] & IMPLEMENTATION_MASK) {
-       case IMPLEMENTATION_FILE:
-               i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
-               table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
-               i = mono_metadata_decode_row_col (table, i - 1, MONO_FILE_NAME);
-               val = mono_metadata_string_heap (assembly->assembly->image, i);
-               n = g_concat_dir_and_file (assembly->assembly->basedir, val);
-               result = (MonoObject*)mono_string_new (mono_object_domain (assembly), n);
-               /* check hash if needed */
-               g_free (n);
-               return result;
-       case IMPLEMENTATION_ASSEMBLYREF:
-       case IMPLEMENTATION_EXP_TYPE:
-               /* FIXME */
-               break;
+               info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
        }
-       return NULL;
+       else {
+               switch (cols [MONO_MANIFEST_IMPLEMENTATION] & IMPLEMENTATION_MASK) {
+               case IMPLEMENTATION_FILE:
+                       i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
+                       table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
+                       mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
+                       val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
+                       info->filename = mono_string_new (mono_object_domain (assembly), val);
+                       if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
+                               info->location = 0;
+                       else
+                               info->location = RESOURCE_LOCATION_EMBEDDED;
+                       break;
+
+               case IMPLEMENTATION_ASSEMBLYREF:
+                       i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
+                       info->assembly = mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]);
+
+                       // Obtain info recursively
+                       ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
+                       info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
+                       break;
+
+               case IMPLEMENTATION_EXP_TYPE:
+                       g_assert_not_reached ();
+                       break;
+               }
+       }
+
+       return TRUE;
 }
 
 static MonoObject*
@@ -2326,6 +2698,40 @@ ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *a
        return (MonoObject*)result;
 }
 
+static MonoArray*
+ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
+{
+       MonoDomain *domain = mono_domain_get();
+       MonoArray *res;
+       MonoClass *klass;
+       int i, module_count = 0, file_count = 0;
+       MonoImage **modules = assembly->assembly->image->modules;
+       MonoTableInfo *table;
+
+       if (modules) {
+               while (modules[module_count])
+                       ++module_count;
+       }
+
+       table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
+       file_count = table->rows;
+
+       g_assert( assembly->assembly->image != NULL);
+       ++module_count;
+
+       klass = mono_class_from_name ( mono_defaults.corlib, "System.Reflection", "Module");
+       res = mono_array_new (domain, klass, module_count + file_count);
+
+       mono_array_set (res, gpointer, 0, mono_module_get_object (domain, assembly->assembly->image));
+       for ( i = 1; i < module_count; ++i )
+               mono_array_set (res, gpointer, i, mono_module_get_object (domain, modules[i]));
+
+       for (i = 0; i < table->rows; ++i)
+               mono_array_set (res, gpointer, module_count + i, mono_module_file_get_object (domain, assembly->assembly->image, i));
+
+       return res;
+}
+
 static MonoReflectionMethod*
 ves_icall_GetCurrentMethod (void) 
 {
@@ -2468,6 +2874,30 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
        return res;
 }
 
+static MonoReflectionType*
+ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
+{
+       MonoDomain *domain = mono_object_domain (module); 
+       MonoClass *klass;
+
+       MONO_ARCH_SAVE_REGS;
+
+       g_assert (module->image);
+       klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
+       return mono_type_get_object (domain, &klass->byval_arg);
+}
+
+static MonoString*
+ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
+{
+       MonoDomain *domain = mono_object_domain (module); 
+
+       MONO_ARCH_SAVE_REGS;
+
+       g_assert (module->image);
+       return mono_string_new (domain, module->image->guid);
+}
+
 static MonoReflectionType*
 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
 {
@@ -2517,7 +2947,7 @@ ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, Mon
                                return NULL;
                        }
                        p++;
-                       klass = mono_array_class_get (&klass->byval_arg, rank);
+                       klass = mono_array_class_get (klass, rank);
                        mono_class_init (klass);
                        break;
                default:
@@ -2528,6 +2958,20 @@ ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, Mon
        return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
 }
 
+static MonoBoolean
+ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
+{
+       MonoType *type;
+       MonoBoolean res;
+
+       MONO_ARCH_SAVE_REGS;
+
+       type = t->type;
+       res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
+
+       return res;
+}
+
 static MonoObject *
 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
                                                   MonoReflectionMethod *info)
@@ -2553,8 +2997,16 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
  * Magic number to convert a time which is relative to
  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
  */
-#define        EPOCH_ADJUST    ((gint64)62135596800L)
+#define        EPOCH_ADJUST    ((guint64)62135596800L)
+
+/*
+ * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
+ */
+#define FILETIME_ADJUST ((guint64)504911232000000000LL)
 
+/*
+ * This returns Now in UTC
+ */
 static gint64
 ves_icall_System_DateTime_GetNow (void)
 {
@@ -2564,7 +3016,7 @@ ves_icall_System_DateTime_GetNow (void)
        
        GetLocalTime (&st);
        SystemTimeToFileTime (&st, &ft);
-       return (gint64)504911232000000000L + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
+       return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
 #else
        /* FIXME: put this in io-layer and call it GetLocalTime */
        struct timeval tv;
@@ -2581,6 +3033,58 @@ ves_icall_System_DateTime_GetNow (void)
 #endif
 }
 
+#ifdef PLATFORM_WIN32
+/* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
+static void
+convert_to_absolute_date(SYSTEMTIME *date)
+{
+#define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
+       static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+       static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+       /* from the calendar FAQ */
+       int a = (14 - date->wMonth) / 12;
+       int y = date->wYear - a;
+       int m = date->wMonth + 12 * a - 2;
+       int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
+
+       /* d is now the day of the week for the first of the month (0 == Sunday) */
+
+       int day_of_week = date->wDayOfWeek;
+
+       /* set day_in_month to the first day in the month which falls on day_of_week */    
+       int day_in_month = 1 + (day_of_week - d);
+       if (day_in_month <= 0)
+               day_in_month += 7;
+
+       /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
+       date->wDay = day_in_month + (date->wDay - 1) * 7;
+       if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
+               date->wDay -= 7;
+}
+#endif
+
+#ifndef PLATFORM_WIN32
+/*
+ * Return's the offset from GMT of a local time.
+ * 
+ *  tm is a local time
+ *  t  is the same local time as seconds.
+ */
+static int 
+gmt_offset(struct tm *tm, time_t t)
+{
+#if defined (HAVE_TM_GMTOFF)
+       return tm->tm_gmtoff;
+#else
+       struct tm g;
+       time_t t2;
+       g = *gmtime(&t);
+       g.tm_isdst = tm->tm_isdst;
+       t2 = mktime(&g);
+       return (int)difftime(t, t2);
+#endif
+}
+#endif
 /*
  * This is heavily based on zdump.c from glibc 2.2.
  *
@@ -2606,12 +3110,30 @@ ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data
 
        long int gmtoff;
        int is_daylight = 0, day;
-       char tzone[10];
+       char tzone [64];
 
        MONO_ARCH_SAVE_REGS;
 
-       if ((year < 1900) || (year > 2100))
-               mono_raise_exception (mono_get_exception_not_implemented ());
+       MONO_CHECK_ARG_NULL (data);
+       MONO_CHECK_ARG_NULL (names);
+
+       (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
+       (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+
+       /* 
+        * no info is better than crashing: we'll need our own tz data to make 
+        * this work properly, anyway. The range is reduced to 1970 .. 2037 because
+        * that is what mktime is guaranteed to support (we get into an infinite loop 
+        * otherwise).
+        */
+       if ((year < 1970) || (year > 2037)) {
+               t = time (NULL);
+               tt = *localtime (&t);
+               strftime (tzone, sizeof (tzone), "%Z", &tt);
+               mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
+               mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
+               return 1;
+       }
 
        memset (&start, 0, sizeof (start));
 
@@ -2619,21 +3141,7 @@ ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data
        start.tm_year = year-1900;
 
        t = mktime (&start);
-#if defined (HAVE_TIMEZONE)
-#define gmt_offset(x) (-1 * (((timezone / 60 / 60) - daylight) * 100))
-#elif defined (HAVE_TM_GMTOFF)
-#define gmt_offset(x) x.tm_gmtoff
-#else
-#error Neither HAVE_TIMEZONE nor HAVE_TM_GMTOFF defined. Rerun autoheader, autoconf, etc.
-#endif
-       
-       gmtoff = gmt_offset (start);
-
-       MONO_CHECK_ARG_NULL (data);
-       MONO_CHECK_ARG_NULL (names);
-
-       (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
-       (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+       gmtoff = gmt_offset (&start, t);
 
        /* For each day of the year, calculate the tm_gmtoff. */
        for (day = 0; day < 365; day++) {
@@ -2642,7 +3150,7 @@ ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data
                tt = *localtime (&t);
 
                /* Daylight saving starts or ends here. */
-               if (gmt_offset (tt) != gmtoff) {
+               if (gmt_offset (&tt, t) != gmtoff) {
                        struct tm tt1;
                        time_t t1;
 
@@ -2651,15 +3159,15 @@ ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data
                        do {
                                t1 -= 3600;
                                tt1 = *localtime (&t1);
-                       } while (gmt_offset (tt1) != gmtoff);
+                       } while (gmt_offset (&tt1, t1) != gmtoff);
 
                        /* Try to find the exact minute when daylight saving starts/ends. */
                        do {
                                t1 += 60;
                                tt1 = *localtime (&t1);
-                       } while (gmt_offset (tt1) == gmtoff);
+                       } while (gmt_offset (&tt1, t1) == gmtoff);
                        
-                       strftime (tzone, 10, "%Z", &tt);
+                       strftime (tzone, sizeof (tzone), "%Z", &tt);
                        
                        /* Write data, if we're already in daylight saving, we're done. */
                        if (is_daylight) {
@@ -2674,16 +3182,14 @@ ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data
 
                        /* This is only set once when we enter daylight saving. */
                        mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
-                       mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (tt) - gmtoff) * 10000000L);
+                       mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
 
-                       gmtoff = gmt_offset (tt);
+                       gmtoff = gmt_offset (&tt, t);
                }
-
-               gmtoff = gmt_offset (tt);
        }
 
        if (!is_daylight) {
-               strftime (tzone, 10, "%Z", &tt);
+               strftime (tzone, sizeof (tzone), "%Z", &tt);
                mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
                mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
                mono_array_set ((*data), gint64, 0, 0);
@@ -2698,8 +3204,11 @@ ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data
        TIME_ZONE_INFORMATION tz_info;
        FILETIME ft;
        int i;
+       int err, tz_id;
 
-       GetTimeZoneInformation (&tz_info);
+       tz_id = GetTimeZoneInformation (&tz_info);
+       if (tz_id == TIME_ZONE_ID_INVALID)
+               return 0;
 
        MONO_CHECK_ARG_NULL (data);
        MONO_CHECK_ARG_NULL (names);
@@ -2716,12 +3225,29 @@ ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data
                        break;
        mono_array_set ((*names), gpointer, 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
 
-       SystemTimeToFileTime (&tz_info.StandardDate, &ft);
-       mono_array_set ((*data), gint64, 1, ((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime);
-       SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
-       mono_array_set ((*data), gint64, 0, ((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime);
-       mono_array_set ((*data), gint64, 3, tz_info.Bias + tz_info.StandardBias);
-       mono_array_set ((*data), gint64, 2, tz_info.Bias + tz_info.DaylightBias);
+       if ((year <= 1601) || (year > 30827)) {
+               /*
+                * According to MSDN, the MS time functions can't handle dates outside
+                * this interval.
+                */
+               return 1;
+       }
+
+       /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
+       if (tz_id != TIME_ZONE_ID_UNKNOWN) {
+               tz_info.StandardDate.wYear = year;
+               convert_to_absolute_date(&tz_info.StandardDate);
+               err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
+               g_assert(err);
+               mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
+               tz_info.DaylightDate.wYear = year;
+               convert_to_absolute_date(&tz_info.DaylightDate);
+               err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
+               g_assert(err);
+               mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
+       }
+       mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
+       mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
 
        return 1;
 #endif
@@ -2755,9 +3281,9 @@ ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
        if (array->bounds == NULL)
                length = array->max_length;
        else {
-               length = 0;
+               length = 1;
                for (i = 0; i < klass->rank; ++ i)
-                       length += array->bounds [i].length;
+                       length *= array->bounds [i].length;
        }
 
        esize = mono_array_element_size (klass);
@@ -2908,7 +3434,10 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
 /*
  * There is no standard way to get at environ.
  */
-extern char **environ;
+#ifndef _MSC_VER
+extern
+#endif
+char **environ;
 
 static MonoArray *
 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
@@ -2973,7 +3502,7 @@ ves_icall_System_Environment_Exit (int result)
 {
        MONO_ARCH_SAVE_REGS;
 
-       mono_profiler_shutdown ();
+       mono_runtime_quit ();
 
        /* we may need to do some cleanup here... */
        exit (result);
@@ -3108,7 +3637,7 @@ mono_install_get_config_dir (void)
     mono_cfg_dir = g_strdup (MONO_CFG_DIR);
     for (i = strlen (mono_cfg_dir) - 1; i >= 0; i--) {
         if (mono_cfg_dir [i] == '/')
-            mono_cfg_dir [i] = '\\';
+            ((char*) mono_cfg_dir) [i] = '\\';
     }
 #endif
   }
@@ -3118,14 +3647,11 @@ mono_install_get_config_dir (void)
 static MonoString *
 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
 {
-       static MonoString *mcpath;
+       MonoString *mcpath;
        gchar *path;
 
        MONO_ARCH_SAVE_REGS;
 
-       if (mcpath != NULL)
-               return mcpath;
-
        path = g_build_path (G_DIR_SEPARATOR_S, mono_cfg_dir, "mono", "machine.config", NULL);
 
 #if defined (PLATFORM_WIN32)
@@ -3143,6 +3669,31 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
        return mcpath;
 }
 
+static MonoString *
+ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
+{
+       MonoString *ipath;
+       gchar *path;
+
+       MONO_ARCH_SAVE_REGS;
+
+       path = g_path_get_dirname (mono_cfg_dir);
+
+#if defined (PLATFORM_WIN32)
+       /* Avoid mixing '/' and '\\' */
+       {
+               gint i;
+               for (i = strlen (path) - 1; i >= 0; i--)
+                       if (path [i] == '/')
+                               path [i] = '\\';
+       }
+#endif
+       ipath = mono_string_new (mono_domain_get (), path);
+       g_free (path);
+
+       return ipath;
+}
+
 static void
 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
 {
@@ -3217,8 +3768,21 @@ ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
        if (method->klass == NULL || (klass = method->klass->parent) == NULL)
                return m;
 
-       if (klass->vtable_size > method->slot)
+       while (result == NULL && klass != NULL && (klass->vtable_size > method->slot))
+       {
                result = klass->vtable [method->slot];
+               if (result == NULL) {
+                       /* It is an abstract method */
+                       int i;
+                       for (i=0; i<klass->method.count; i++) {
+                               if (klass->methods [i]->slot == method->slot) {
+                                       result = klass->methods [i];
+                                       break;
+                               }
+                       }
+               }
+               klass = klass->parent;
+       }
 
        if (result == NULL)
                return m;
@@ -3226,6 +3790,133 @@ ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
        return mono_method_get_object (mono_domain_get (), result, NULL);
 }
 
+static void
+mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       iter->sig = *(MonoMethodSignature**)argsp;
+       
+       g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
+       g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
+
+       iter->next_arg = 0;
+       /* FIXME: it's not documented what start is exactly... */
+       iter->args = start? start: argsp + sizeof (gpointer);
+       iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
+
+       // g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos);
+}
+
+static MonoTypedRef
+mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
+{
+       gint i, align, arg_size;
+       MonoTypedRef res;
+       MONO_ARCH_SAVE_REGS;
+
+       i = iter->sig->sentinelpos + iter->next_arg;
+
+       g_assert (i < iter->sig->param_count);
+
+       res.type = iter->sig->params [i];
+       /* FIXME: endianess issue... */
+       res.value = iter->args;
+       arg_size = mono_type_stack_size (res.type, &align);
+       iter->args = (char*)iter->args + arg_size;
+       iter->next_arg++;
+
+       //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
+
+       return res;
+}
+
+static MonoTypedRef
+mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
+{
+       gint i, align, arg_size;
+       MonoTypedRef res;
+       MONO_ARCH_SAVE_REGS;
+
+       i = iter->sig->sentinelpos + iter->next_arg;
+
+       g_assert (i < iter->sig->param_count);
+
+       while (i < iter->sig->param_count) {
+               if (!mono_metadata_type_equal (type, iter->sig->params [i]))
+                       continue;
+               res.type = iter->sig->params [i];
+               /* FIXME: endianess issue... */
+               res.value = iter->args;
+               arg_size = mono_type_stack_size (res.type, &align);
+               iter->args = (char*)iter->args + arg_size;
+               iter->next_arg++;
+               //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
+               return res;
+       }
+       //g_print ("arg type 0x%02x not found\n", res.type->type);
+
+       res.type = NULL;
+       res.value = NULL;
+       return res;
+}
+
+static MonoType*
+mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
+{
+       gint i;
+       MONO_ARCH_SAVE_REGS;
+       
+       i = iter->sig->sentinelpos + iter->next_arg;
+
+       g_assert (i < iter->sig->param_count);
+
+       return iter->sig->params [i];
+}
+
+static MonoObject*
+mono_TypedReference_ToObject (MonoTypedRef tref)
+{
+       MonoClass *klass;
+       MONO_ARCH_SAVE_REGS;
+
+       if (MONO_TYPE_IS_REFERENCE (tref.type)) {
+               MonoObject** objp = tref.value;
+               return *objp;
+       }
+       klass = mono_class_from_mono_type (tref.type);
+
+       return mono_value_box (mono_domain_get (), klass, tref.value);
+}
+
+static void
+prelink_method (MonoMethod *method)
+{
+       if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
+               return;
+       mono_lookup_pinvoke_call (method);
+       /* create the wrapper, too? */
+}
+
+static void
+ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
+{
+       MONO_ARCH_SAVE_REGS;
+       prelink_method (method->method);
+}
+
+static void
+ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
+{
+       MonoClass *klass = mono_class_from_mono_type (type->type);
+       int i;
+       MONO_ARCH_SAVE_REGS;
+
+       mono_class_init (klass);
+       for (i = 0; i < klass->method.count; ++i)
+               prelink_method (klass->methods [i]);
+}
+
 /* icall map */
 
 static gconstpointer icall_map [] = {
@@ -3243,19 +3934,32 @@ static gconstpointer icall_map [] = {
        "System.Array::FastCopy",         ves_icall_System_Array_FastCopy,
        "System.Array::Clone",            mono_array_clone,
 
+       /*
+        * System.ArgIterator
+        */
+       "System.ArgIterator::Setup",                            mono_ArgIterator_Setup,
+       "System.ArgIterator::IntGetNextArg()",                  mono_ArgIterator_IntGetNextArg,
+       "System.ArgIterator::IntGetNextArg(intptr)", mono_ArgIterator_IntGetNextArgT,
+       "System.ArgIterator::IntGetNextArgType",                mono_ArgIterator_IntGetNextArgType,
+
+       /*
+        * System.TypedReference
+        */
+       "System.TypedReference::ToObject",                      mono_TypedReference_ToObject,
+
        /*
         * System.Object
         */
        "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
        "System.Object::GetType", ves_icall_System_Object_GetType,
-       "System.Object::GetHashCode", ves_icall_System_Object_GetHashCode,
+       "System.Object::InternalGetHashCode", ves_icall_System_Object_GetHashCode,
        "System.Object::obj_address", ves_icall_System_Object_obj_address,
 
        /*
         * System.ValueType
         */
        "System.ValueType::GetHashCode", ves_icall_System_ValueType_GetHashCode,
-       "System.ValueType::Equals", ves_icall_System_ValueType_Equals,
+       "System.ValueType::InternalEquals", ves_icall_System_ValueType_Equals,
 
        /*
         * System.String
@@ -3314,6 +4018,7 @@ static gconstpointer icall_map [] = {
        "System.AppDomain::InternalSetContext", ves_icall_System_AppDomain_InternalSetContext,
        "System.AppDomain::InternalGetContext", ves_icall_System_AppDomain_InternalGetContext,
        "System.AppDomain::InternalGetDefaultContext", ves_icall_System_AppDomain_InternalGetDefaultContext,
+       "System.AppDomain::InternalGetProcessGuid", ves_icall_System_AppDomain_InternalGetProcessGuid,
 
        /*
         * System.AppDomainSetup
@@ -3324,6 +4029,7 @@ static gconstpointer icall_map [] = {
         * System.Double
         */
        "System.Double::ParseImpl",    mono_double_ParseImpl,
+       "System.Double::AssertEndianity", ves_icall_System_Double_AssertEndianity,
 
        /*
         * System.Decimal
@@ -3363,7 +4069,6 @@ static gconstpointer icall_map [] = {
         */
        "System.Reflection.MonoMethodInfo::get_method_info", ves_icall_get_method_info,
        "System.Reflection.MonoMethodInfo::get_parameter_info", ves_icall_get_parameter_info,
-       "System.Reflection.MonoFieldInfo::get_field_info", ves_icall_get_field_info,
        "System.Reflection.MonoPropertyInfo::get_property_info", ves_icall_get_property_info,
        "System.Reflection.MonoEventInfo::get_event_info", ves_icall_get_event_info,
        "System.Reflection.MonoMethod::InternalInvoke", ves_icall_InternalInvoke,
@@ -3371,6 +4076,7 @@ static gconstpointer icall_map [] = {
        "System.Reflection.MethodBase::GetCurrentMethod", ves_icall_GetCurrentMethod,
        "System.MonoCustomAttrs::GetCustomAttributes", mono_reflection_get_custom_attrs,
        "System.Reflection.Emit.CustomAttributeBuilder::GetBlob", mono_reflection_get_custom_attrs_blob,
+       "System.Reflection.MonoField::GetParentType", ves_icall_MonoField_GetParentType,
        "System.Reflection.MonoField::GetValueInternal", ves_icall_MonoField_GetValueInternal,
        "System.Reflection.MonoField::SetValueInternal", ves_icall_FieldInfo_SetValueInternal,
        "System.Reflection.Emit.SignatureHelper::get_signature_local", mono_reflection_sighelper_get_signature_local,
@@ -3391,10 +4097,18 @@ static gconstpointer icall_map [] = {
        "System.Reflection.Emit.TypeBuilder::setup_internal_class", mono_reflection_setup_internal_class,
        "System.Reflection.Emit.TypeBuilder::create_internal_class", mono_reflection_create_internal_class,
        "System.Reflection.Emit.TypeBuilder::create_runtime_class", mono_reflection_create_runtime_class,
+       "System.Reflection.Emit.TypeBuilder::setup_generic_class", mono_reflection_setup_generic_class,
+
+       /*
+        * TypeBuilder generics icalls.
+        */
+       "System.Reflection.Emit.TypeBuilder::get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter,
+       "System.Reflection.Emit.TypeBuilder::define_generic_parameter", ves_icall_TypeBuilder_define_generic_parameter,
        
        /*
-        * MethodBuilder
+        * MethodBuilder generic icalls.
         */
+       "System.Reflection.Emit.MethodBuilder::define_generic_parameter", ves_icall_MethodBuilder_define_generic_parameter,
        
        /*
         * System.Type
@@ -3403,9 +4117,24 @@ static gconstpointer icall_map [] = {
        "System.Type::internal_from_handle", ves_icall_type_from_handle,
        "System.MonoType::get_attributes", ves_icall_get_attributes,
        "System.Type::type_is_subtype_of", ves_icall_type_is_subtype_of,
+       "System.Type::type_is_assignable_from", ves_icall_type_is_assignable_from,
        "System.Type::Equals", ves_icall_type_Equals,
        "System.Type::GetTypeCode", ves_icall_type_GetTypeCode,
        "System.Type::GetInterfaceMapData", ves_icall_Type_GetInterfaceMapData,
+       "System.Type::IsArrayImpl", ves_icall_Type_IsArrayImpl,
+
+       /* Type generics icalls */
+       "System.Type::GetGenericArguments", ves_icall_Type_GetGenericArguments,
+       "System.Type::GetGenericParameterPosition", ves_icall_Type_GetGenericParameterPosition,
+       "System.Type::get_IsGenericTypeDefinition", ves_icall_Type_get_IsGenericTypeDefinition,
+       "System.Type::GetGenericTypeDefinition_impl", ves_icall_Type_GetGenericTypeDefinition_impl,
+       "System.Type::BindGenericParameters", ves_icall_Type_BindGenericParameters,
+       "System.Type::get_IsGenericInstance", ves_icall_Type_get_IsGenericInstance,
+       
+       "System.MonoType::get_HasGenericArguments", ves_icall_MonoType_get_HasGenericArguments,
+       "System.MonoType::get_IsGenericParameter", ves_icall_MonoType_get_IsGenericParameter,
+       "System.MonoType::get_DeclaringMethod", ves_icall_MonoType_get_DeclaringMethod,
+
 
        /*
         * System.Reflection.FieldInfo
@@ -3446,6 +4175,9 @@ static gconstpointer icall_map [] = {
        "System.Threading.NativeEventCalls::CreateEvent_internal", ves_icall_System_Threading_Events_CreateEvent_internal,
        "System.Threading.NativeEventCalls::SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal,
        "System.Threading.NativeEventCalls::ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal,
+       "System.Threading.NativeEventCalls::CloseEvent_internal", ves_icall_System_Threading_Events_CloseEvent_internal,
+       "System.Threading.ThreadPool::GetAvailableThreads", ves_icall_System_Threading_ThreadPool_GetAvailableThreads,
+       "System.Threading.ThreadPool::GetMaxThreads", ves_icall_System_Threading_ThreadPool_GetMaxThreads,
 
        /*
         * System.Threading.WaitHandle
@@ -3491,6 +4223,8 @@ static gconstpointer icall_map [] = {
        "System.Runtime.InteropServices.Marshal::StringToHGlobalAuto", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi,
        "System.Runtime.InteropServices.Marshal::StringToHGlobalUni", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni,
        "System.Runtime.InteropServices.Marshal::DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure,
+       "System.Runtime.InteropServices.Marshal::Prelink", ves_icall_System_Runtime_InteropServices_Marshal_Prelink,
+       "System.Runtime.InteropServices.Marshal::PrelinkAll", ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll,
 
 
        "System.Reflection.Assembly::LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom,
@@ -3499,14 +4233,24 @@ static gconstpointer icall_map [] = {
        "System.Reflection.Assembly::FillName", ves_icall_System_Reflection_Assembly_FillName,
        "System.Reflection.Assembly::get_code_base", ves_icall_System_Reflection_Assembly_get_code_base,
        "System.Reflection.Assembly::get_location", ves_icall_System_Reflection_Assembly_get_location,
+       "System.Reflection.Assembly::InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion,
        "System.Reflection.Assembly::GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly,
        "System.Reflection.Assembly::GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly,
        "System.Reflection.Assembly::GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly,
        "System.Reflection.Assembly::get_EntryPoint", ves_icall_System_Reflection_Assembly_get_EntryPoint,
        "System.Reflection.Assembly::GetManifestResourceNames", ves_icall_System_Reflection_Assembly_GetManifestResourceNames,
        "System.Reflection.Assembly::GetManifestResourceInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInternal,
+       "System.Reflection.Assembly::GetManifestResourceInfoInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal,
        "System.Reflection.Assembly::GetFilesInternal", ves_icall_System_Reflection_Assembly_GetFilesInternal,
        "System.Reflection.Assembly::GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_GetReferencedAssemblies,
+       "System.Reflection.Assembly::GetNamespaces", ves_icall_System_Reflection_Assembly_GetNamespaces,
+       "System.Reflection.Assembly::GetModulesInternal", ves_icall_System_Reflection_Assembly_GetModulesInternal,
+
+       /*
+        * System.Reflection.Module
+        */
+       "System.Reflection.Module::GetGlobalType", ves_icall_System_Reflection_Module_GetGlobalType,
+       "System.Reflection.Module::GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal,
 
        /*
         * System.MonoType.
@@ -3518,6 +4262,7 @@ static gconstpointer icall_map [] = {
        "System.MonoType::get_BaseType", ves_icall_get_type_parent,
        "System.MonoType::get_Module", ves_icall_MonoType_get_Module,
        "System.MonoType::IsPointerImpl", ves_icall_type_ispointer,
+       "System.MonoType::IsPrimitiveImpl", ves_icall_type_isprimitive,
        "System.MonoType::IsByRefImpl", ves_icall_type_isbyref,
        "System.MonoType::GetField", ves_icall_Type_GetField,
        "System.MonoType::GetFields", ves_icall_Type_GetFields,
@@ -3528,6 +4273,7 @@ static gconstpointer icall_map [] = {
        "System.MonoType::InternalGetEvent", ves_icall_MonoType_GetEvent,
        "System.MonoType::GetInterfaces", ves_icall_Type_GetInterfaces,
        "System.MonoType::GetNestedTypes", ves_icall_Type_GetNestedTypes,
+       "System.MonoType::GetNestedType", ves_icall_Type_GetNestedType,
 
        /*
         * System.Net.Sockets I/O Services
@@ -3611,7 +4357,7 @@ static gconstpointer icall_map [] = {
        "System.Buffer::GetByteInternal", ves_icall_System_Buffer_GetByteInternal,
        "System.Buffer::SetByteInternal", ves_icall_System_Buffer_SetByteInternal,
        "System.Buffer::BlockCopyInternal", ves_icall_System_Buffer_BlockCopyInternal,
-
+       
        /*
         * System.IO.MonoIO
         */
@@ -3647,6 +4393,7 @@ static gconstpointer icall_map [] = {
        "System.IO.MonoIO::get_AltDirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar,
        "System.IO.MonoIO::get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparator,
        "System.IO.MonoIO::get_InvalidPathChars", ves_icall_System_IO_MonoIO_get_InvalidPathChars,
+       "System.IO.MonoIO::GetTempPath(string&)", ves_icall_System_IO_MonoIO_GetTempPath,
 
        /*
         * System.Math
@@ -3734,7 +4481,7 @@ static gconstpointer icall_map [] = {
        "System.Diagnostics.Process::GetPid_internal()", ves_icall_System_Diagnostics_Process_GetPid_internal,
        "System.Diagnostics.Process::Process_free_internal(intptr)", ves_icall_System_Diagnostics_Process_Process_free_internal,
        "System.Diagnostics.Process::GetModules_internal()", ves_icall_System_Diagnostics_Process_GetModules_internal,
-       "System.Diagnostics.Process::Start_internal(string,string,intptr,intptr,intptr,ProcInfo&)", ves_icall_System_Diagnostics_Process_Start_internal,
+       "System.Diagnostics.Process::Start_internal(string,string,intptr,intptr,intptr,System.Diagnostics.Process/ProcInfo&)", ves_icall_System_Diagnostics_Process_Start_internal,
        "System.Diagnostics.Process::WaitForExit_internal(intptr,int)", ves_icall_System_Diagnostics_Process_WaitForExit_internal,
        "System.Diagnostics.Process::ExitTime_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitTime_internal,
        "System.Diagnostics.Process::StartTime_internal(intptr)", ves_icall_System_Diagnostics_Process_StartTime_internal,
@@ -3792,6 +4539,24 @@ static gconstpointer icall_map [] = {
        "System.Activator::CreateInstanceInternal",
        ves_icall_System_Activator_CreateInstanceInternal,
 
+       /* 
+        * System.Web
+        */
+       "System.Web.Util.ICalls::GetMachineConfigPath",
+       ves_icall_System_Configuration_DefaultConfig_get_machine_config_path,
+
+       "System.Web.Util.ICalls::GetMachineInstallDirectory",
+       ves_icall_System_Web_Util_ICalls_get_machine_install_dir,
+
+       /*
+        * System.Globalization
+        */
+       "System.Globalization.CultureInfo::construct_internal_locale(string)", ves_icall_System_Globalization_CultureInfo_construct_internal_locale,
+       "System.Globalization.CultureInfo::construct_compareinfo(object,string)", ves_icall_System_Globalization_CultureInfo_construct_compareinfo,
+       "System.Globalization.CompareInfo::internal_compare(string,string,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_internal_compare,
+       "System.Globalization.CompareInfo::free_internal_collator()", ves_icall_System_Globalization_CompareInfo_free_internal_collator,
+       "System.Globalization.CompareInfo::assign_sortkey(object,string,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_assign_sortkey,
+
        /*
         * add other internal calls here
         */