Check if the override declaration is visible to the body.
[mono.git] / mono / metadata / icall.c
index 385940f4f19ac2abbdd3b381bc0daa80bc9edc5c..beb055f8978e11d3cdff3198a189093c23c7f623 100644 (file)
@@ -77,6 +77,7 @@
 #include <mono/utils/mono-string.h>
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-io-portability.h>
 
 #if defined (HOST_WIN32)
 #include <windows.h>
@@ -245,7 +246,8 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
                        "value", "not a widening conversion")); \
 }G_STMT_END
 
-#define INVALID_CAST G_STMT_START{\
+#define INVALID_CAST G_STMT_START{ \
+               mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
        mono_raise_exception (mono_get_exception_invalid_cast ()); \
 }G_STMT_END
 
@@ -687,7 +689,6 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
        void * source_addr;
        MonoClass *src_class;
        MonoClass *dest_class;
-       int i;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -711,6 +712,10 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
 
        /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
        if (src_class == mono_defaults.object_class && dest_class->valuetype) {
+               // FIXME: This is racy
+               return FALSE;
+               /*
+                 int i;
                int has_refs = dest_class->has_references;
                for (i = source_idx; i < source_idx + length; ++i) {
                        MonoObject *elem = mono_array_get (source, MonoObject*, i);
@@ -731,6 +736,7 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
                                memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
                }
                return TRUE;
+               */
        }
 
        /* Check if we're copying a char[] <==> (u)short[] */
@@ -741,13 +747,18 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
                if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
                        ;
                /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
-               else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
+               else if (mono_class_is_subclass_of (dest_class, src_class, FALSE)) {
+                       // FIXME: This is racy
+                       return FALSE;
+                       /*
+                         int i;
                        for (i = source_idx; i < source_idx + length; ++i) {
                                MonoObject *elem = mono_array_get (source, MonoObject*, i);
                                if (elem && !mono_object_isinst (elem, dest_class))
                                        return FALSE;
                        }
-               else
+                       */
+               } else
                        return FALSE;
        }
 
@@ -825,12 +836,9 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoAr
        int align;
        const char *field_data;
 
-       if (MONO_TYPE_IS_REFERENCE (type) ||
-                       (type->type == MONO_TYPE_VALUETYPE &&
-                               (!mono_type_get_class (type) ||
-                               mono_type_get_class (type)->has_references))) {
+       if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
                MonoException *exc = mono_get_exception_argument("array",
-                       "Cannot initialize array containing references");
+                       "Cannot initialize array of non-primitive type.");
                mono_raise_exception (exc);
        }
 
@@ -2440,7 +2448,7 @@ ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
 
        /*we might inflate to the GTD*/
        if (class->generic_class && !mono_verifier_class_is_valid_generic_instantiation (class))
-               mono_raise_exception (mono_get_exception_argument ("method", "Invalid generic arguments"));
+               mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
 
        return mono_type_get_object (mono_object_domain (type), geninst);
 }
@@ -5860,6 +5868,8 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
                /* Creating a trampoline would leak memory */
                func = mono_compile_method (method);
        } else {
+               if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
+                       method = mono_object_get_virtual_method (target, method);
                func = mono_create_ftnptr (mono_domain_get (),
                        mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE));
        }
@@ -6299,12 +6309,13 @@ ves_icall_System_Environment_get_Platform (void)
 #elif defined(__MACH__)
        /* OSX */
        //
-       // For compatibility with our client code, this will be 4 for a while.
-       // We will eventually move to 6 to match .NET, but it requires all client
-       // code to be updated and the documentation everywhere to be updated 
-       // first.
+       // Notice that the value is hidden from user code, and only exposed
+       // to mscorlib.   This is due to Mono's Unix/MacOS code predating the
+       // define and making assumptions based on Unix/128/4 values before there
+       // was a MacOS define.    Lots of code would assume that not-Unix meant
+       // Windows, but in this case, it would be OSX. 
        //
-       return 4;
+       return 6;
 #else
        /* Unix */
        return 4;
@@ -6911,7 +6922,7 @@ get_bundled_app_config (void)
        const gchar *app_config;
        MonoDomain *domain;
        MonoString *file;
-       gchar *config_file;
+       gchar *config_file_name, *config_file_path;
        gsize len;
        gchar *module;
 
@@ -6923,15 +6934,20 @@ get_bundled_app_config (void)
                return NULL;
 
        // Retrieve config file and remove the extension
-       config_file = mono_string_to_utf8 (file);
-       len = strlen (config_file) - strlen (".config");
+       config_file_name = mono_string_to_utf8 (file);
+       config_file_path = mono_portability_find_file (config_file_name, TRUE);
+       if (!config_file_path)
+               config_file_path = config_file_name;
+       len = strlen (config_file_path) - strlen (".config");
        module = g_malloc0 (len + 1);
-       memcpy (module, config_file, len);
+       memcpy (module, config_file_path, len);
        // Get the config file from the module name
        app_config = mono_config_string_for_assembly_file (module);
        // Clean-up
        g_free (module);
-       g_free (config_file);
+       if (config_file_name != config_file_path)
+               g_free (config_file_name);
+       g_free (config_file_path);
 
        if (!app_config)
                return NULL;
@@ -7049,6 +7065,7 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
        MonoClass *klass, *parent;
        MonoMethod *method = m->method;
        MonoMethod *result = NULL;
+       int slot;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -7060,6 +7077,10 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
            method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
                return m;
 
+       slot = mono_method_get_vtable_slot (method);
+       if (slot == -1)
+               return m;
+
        klass = method->klass;
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
@@ -7068,7 +7089,7 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
                /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
                for (parent = klass->parent; parent != NULL; parent = parent->parent) {
                        mono_class_setup_vtable (parent);
-                       if (parent->vtable_size <= method->slot)
+                       if (parent->vtable_size <= slot)
                                break;
                        klass = parent;
                }
@@ -7084,15 +7105,17 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
        /*This is possible if definition == FALSE.
         * Do it here to be really sure we don't read invalid memory.
         */
-       if (method->slot >= klass->vtable_size)
+       if (slot >= klass->vtable_size)
                return m;
 
-       result = klass->vtable [method->slot];
+       mono_class_setup_vtable (klass);
+
+       result = klass->vtable [slot];
        if (result == NULL) {
                /* It is an abstract method */
                gpointer iter = NULL;
                while ((result = mono_class_get_methods (klass, &iter)))
-                       if (result->slot == method->slot)
+                       if (result->slot == slot)
                                break;
        }
 
@@ -7472,12 +7495,14 @@ custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
 {
        MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
        MonoArray *res;
+       MonoError error;
 
        if (attr_class)
                mono_class_init_or_throw (attr_class);
 
-       res = mono_reflection_get_custom_attrs_by_type (obj, attr_class);
-
+       res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
        if (mono_loader_get_last_error ()) {
                mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
                g_assert_not_reached ();