#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>
"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
void * source_addr;
MonoClass *src_class;
MonoClass *dest_class;
- int i;
MONO_ARCH_SAVE_REGS;
/* 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);
memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
}
return TRUE;
+ */
}
/* Check if we're copying a char[] <==> (u)short[] */
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;
}
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);
}
/*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);
}
/* 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));
}
#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;
const gchar *app_config;
MonoDomain *domain;
MonoString *file;
- gchar *config_file;
+ gchar *config_file_name, *config_file_path;
gsize len;
gchar *module;
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;
MonoClass *klass, *parent;
MonoMethod *method = m->method;
MonoMethod *result = NULL;
+ int slot;
MONO_ARCH_SAVE_REGS;
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;
/* 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;
}
/*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;
}
{
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 ();