#include <mono/metadata/mono-perfcounters.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/mono-ptr-array.h>
+#include <mono/metadata/verify-internals.h>
#include <mono/io-layer/io-layer.h>
#include <mono/utils/strtod.h>
#include <mono/utils/monobitset.h>
#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);
}
}
static gint32
-ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
+ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
{
MONO_ARCH_SAVE_REGS;
MONO_CHECK_ARG_NULL (obj);
- return mono_image_create_token (mb->dynamic_image, obj, TRUE, TRUE);
+ return mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE);
}
static gint32
return type_array_from_modifiers (field->field->parent->image, type, optional);
}
+static int
+vell_icall_get_method_attributes (MonoMethod *method)
+{
+ return method->flags;
+}
+
static void
ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
{
+ MonoError error;
MonoDomain *domain = mono_domain_get ();
MonoMethodSignature* sig;
MONO_ARCH_SAVE_REGS;
- sig = mono_method_signature (method);
- if (!sig) {
- g_assert (mono_loader_get_last_error ());
- mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
- }
+ sig = mono_method_signature_checked (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+
MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &method->klass->byval_arg));
MONO_STRUCT_SETREF (info, ret, mono_type_get_object (domain, sig->ret));
static void
ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
{
+ MonoError error;
MonoClassField *cf = field->field;
+ MonoType *type;
gchar *v;
MONO_ARCH_SAVE_REGS;
if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
mono_security_core_clr_ensure_reflection_access_field (cf);
+ type = mono_field_get_type_checked (cf, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+
v = (gchar *) value;
- if (!cf->type->byref) {
- switch (cf->type->type) {
+ if (!type->byref) {
+ switch (type->type) {
case MONO_TYPE_U1:
case MONO_TYPE_I1:
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I8:
case MONO_TYPE_R8:
case MONO_TYPE_VALUETYPE:
+ case MONO_TYPE_PTR:
if (v != NULL)
v += sizeof (MonoObject);
break;
/* Do nothing */
break;
case MONO_TYPE_GENERICINST: {
- MonoGenericClass *gclass = cf->type->data.generic_class;
+ MonoGenericClass *gclass = type->data.generic_class;
g_assert (!gclass->context.class_inst->is_open);
- if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
- MonoClass *nklass = mono_class_from_mono_type (cf->type);
+ if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
+ MonoClass *nklass = mono_class_from_mono_type (type);
MonoObject *nullable;
/*
}
default:
g_error ("type 0x%x not handled in "
- "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
+ "ves_icall_FieldInfo_SetValueInternal", type->type);
return;
}
}
- if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+ if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, TRUE);
if (!vtable->initialized)
mono_runtime_class_init (vtable);
mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type"));
class = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (class);
return class->rank;
}
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
if (klass->generic_container) {
MonoGenericContainer *container = klass->generic_container;
return NULL;
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
if (klass->generic_container) {
return type; /* check this one */
static MonoReflectionType*
ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
{
+ MonoClass *class;
MonoType *geninst, **types;
int i, count;
if (!geninst)
return NULL;
+ class = mono_class_from_mono_type (geninst);
+
+ /*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 ("typeArguments", "Invalid generic arguments"));
+
return mono_type_get_object (mono_object_domain (type), geninst);
}
int len;
MonoTypeEnum def_type;
+ if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
+ continue;
if (strcmp ("value__", mono_field_get_name (field)) == 0)
continue;
if (mono_field_is_deleted (field))
int (*compare_func) (const char *s1, const char *s2) = NULL;
domain = ((MonoObject *)type)->vtable->domain;
klass = startklass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
if (!name)
mono_raise_exception (mono_get_exception_argument_null ("name"));
mono_raise_exception (mono_class_get_exception_for_failure (klass));
iter = NULL;
- while ((field = mono_class_get_fields (klass, &iter))) {
+ while ((field = mono_class_get_fields_lazy (klass, &iter))) {
+ guint32 flags = mono_field_get_flags (field);
match = 0;
- if (field->type == NULL)
- continue;
- if (mono_field_is_deleted (field))
+ if (mono_field_is_deleted_with_flags (field, flags))
continue;
- if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
+ if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
if (bflags & BFLAGS_Public)
match++;
- } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
+ } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
if (bflags & BFLAGS_NonPublic) {
match++;
}
if (!match)
continue;
match = 0;
- if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+ if (flags & FIELD_ATTRIBUTE_STATIC) {
if (bflags & BFLAGS_Static)
if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
match++;
aname->revision = name->revision;
aname->hashalg = name->hash_alg;
aname->versioncompat = 1; /* SameMachine (default) */
+ aname->processor_architecture = name->arch;
if (by_default_version)
MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
MonoString *res;
gchar *name;
- name = g_strdup_printf (
- "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
- mass->aname.name,
- mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
- mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
- mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
- (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
-
+ name = mono_stringify_assembly_name (&mass->aname);
res = mono_string_new (domain, name);
g_free (name);
}
static gboolean
-mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
-{
- guint32 cols [MONO_MEMBERREF_SIZE];
- const char *sig;
- mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
- sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
- mono_metadata_decode_blob_size (sig, &sig);
- return (*sig != 0x6);
+mono_memberref_is_method (MonoImage *image, guint32 token)
+{
+ if (!image->dynamic) {
+ guint32 cols [MONO_MEMBERREF_SIZE];
+ const char *sig;
+ mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
+ sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
+ mono_metadata_decode_blob_size (sig, &sig);
+ return (*sig != 0x6);
+ } else {
+ MonoClass *handle_class;
+
+ if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL))
+ return FALSE;
+
+ return mono_defaults.methodhandle_class == handle_class;
+ }
}
static void
}
if (image->dynamic) {
- if (type_args || method_args)
- mono_raise_exception (mono_get_exception_not_implemented (NULL));
- klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
- if (!klass)
- return NULL;
- return &klass->byval_arg;
+ if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
+ klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+ return klass ? &klass->byval_arg : NULL;
+ }
+
+ init_generic_context_from_args (&context, type_args, method_args);
+ klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
+ return klass ? &klass->byval_arg : NULL;
}
if ((index <= 0) || (index > image->tables [table].rows)) {
}
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_class (image, token, FALSE, NULL, NULL);
+ if (table == MONO_TABLE_METHOD)
+ return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+
+ if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ init_generic_context_from_args (&context, type_args, method_args);
+ return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
}
if ((index <= 0) || (index > image->tables [table].rows)) {
*error = ResolveTokenError_OutOfRange;
return NULL;
}
- if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
+ if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
*error = ResolveTokenError_BadTable;
return NULL;
}
}
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_class (image, token, FALSE, NULL, NULL);
+ if (table == MONO_TABLE_FIELD)
+ return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+
+ if (mono_memberref_is_method (image, token)) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ init_generic_context_from_args (&context, type_args, method_args);
+ return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
}
if ((index <= 0) || (index > image->tables [table].rows)) {
*error = ResolveTokenError_OutOfRange;
return NULL;
}
- if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
+ if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
*error = ResolveTokenError_BadTable;
return NULL;
}
return NULL;
}
case MONO_TABLE_MEMBERREF:
- if (mono_metadata_memberref_is_method (image, token)) {
+ if (mono_memberref_is_method (image, token)) {
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);
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
check_for_invalid_type (klass);
if (rank == 0) //single dimentional array
/* 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;
static MonoArray *
ves_icall_System_Environment_GetLogicalDrives (void)
{
- gunichar2 buf [128], *ptr, *dname;
+ gunichar2 buf [256], *ptr, *dname;
gunichar2 *u16;
guint initial_size = 127, size = 128;
gint ndrives;
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 ();