#include <mono/metadata/security-core-clr.h>
#include <mono/metadata/mono-perfcounters.h>
#include <mono/metadata/mono-debug.h>
+#include <mono/metadata/mono-ptr-array.h>
#include <mono/io-layer/io-layer.h>
#include <mono/utils/strtod.h>
#include <mono/utils/monobitset.h>
#include <mono/utils/mono-proclib.h>
#include <mono/utils/mono-string.h>
#include <mono/utils/mono-error-internals.h>
+#include <mono/utils/mono-mmap.h>
#if defined (HOST_WIN32)
#include <windows.h>
#endif
#include "decimal.h"
+extern MonoString* ves_icall_System_Environment_GetOSVersionString (void) MONO_INTERNAL;
+
static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
static MonoArray*
type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
-/* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
- * It works by allocating an initial small array on stack and only going to malloc'd memory if needed.
- */
-typedef struct {
- void **data;
- int size;
- int capacity;
-} MonoPtrArray;
-
-#define MONO_PTR_ARRAY_MAX_ON_STACK (16)
-
-#define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
- (ARRAY).size = 0; \
- (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
- (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, NULL) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
-} while (0)
-
-#define mono_ptr_array_destroy(ARRAY) do {\
- if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
- mono_gc_free_fixed ((ARRAY).data); \
-} while (0)
-
-#define mono_ptr_array_append(ARRAY, VALUE) do { \
- if ((ARRAY).size >= (ARRAY).capacity) {\
- void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \
- memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
- if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
- mono_gc_free_fixed ((ARRAY).data); \
- (ARRAY).data = __tmp; \
- (ARRAY).capacity *= 2;\
- }\
- ((ARRAY).data [(ARRAY).size++] = VALUE); \
-} while (0)
-
-#define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \
- ((ARRAY).data [(IDX)] = VALUE); \
-} while (0)
-
-#define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)])
-
-#define mono_ptr_array_size(ARRAY) ((ARRAY).size)
-
-
static inline MonoBoolean
is_generic_parameter (MonoType *type)
{
return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
}
+static void
+mono_class_init_or_throw (MonoClass *klass)
+{
+ if (!mono_class_init (klass))
+ mono_raise_exception (mono_class_get_exception_for_failure (klass));
+}
+
/*
* We expect a pointer to a char, not a string
*/
*result = strtod (ptr, &endptr);
#else
if (*ptr){
-#ifdef _EGLIB_MAJOR
- /* Need to lock here because EGLIB (#464316) has locking defined as no-ops, and that breaks mono_strtod */
+ /* mono_strtod () is not thread-safe */
EnterCriticalSection (&mono_strtod_mutex);
*result = mono_strtod (ptr, &endptr);
LeaveCriticalSection (&mono_strtod_mutex);
-#else
- *result = mono_strtod (ptr, &endptr);
-#endif
}
#endif
static MonoArray *
ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
{
- MonoClass *aklass;
+ MonoClass *aklass, *klass;
MonoArray *array;
- mono_array_size_t *sizes, i;
+ uintptr_t *sizes, i;
gboolean bounded = FALSE;
MONO_ARCH_SAVE_REGS;
if (mono_array_get (lengths, gint32, i) < 0)
mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
+ klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+
if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
/* vectors are not the same as one dimensional arrays with no-zero bounds */
bounded = TRUE;
else
bounded = FALSE;
- aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
+ aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
- sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2);
+ sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
for (i = 0; i < aklass->rank; ++i) {
sizes [i] = mono_array_get (lengths, guint32, i);
if (bounds)
sizes [i + aklass->rank] = 0;
}
- array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
+ array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank);
return array;
}
static MonoArray *
ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
{
- MonoClass *aklass;
+ MonoClass *aklass, *klass;
MonoArray *array;
- mono_array_size_t *sizes, i;
+ uintptr_t *sizes, i;
gboolean bounded = FALSE;
MONO_ARCH_SAVE_REGS;
(mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX))
mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
+ klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+
if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
/* vectors are not the same as one dimensional arrays with no-zero bounds */
bounded = TRUE;
else
bounded = FALSE;
- aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
+ aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
- sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2);
+ sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
for (i = 0; i < aklass->rank; ++i) {
sizes [i] = mono_array_get (lengths, guint64, i);
if (bounds)
sizes [i + aklass->rank] = 0;
}
- array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
+ array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank);
return array;
}
ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
{
gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
- mono_array_size_t length;
+ uintptr_t length;
MONO_ARCH_SAVE_REGS;
}
}
+static MonoBoolean
+ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
+{
+ guint8 *stack_addr;
+ guint8 *current;
+ size_t stack_size;
+ /* later make this configurable and per-arch */
+ int min_size = 4096 * 4 * sizeof (void*);
+ mono_thread_get_stack_bounds (&stack_addr, &stack_size);
+ /* if we have no info we are optimistic and assume there is enough room */
+ if (!stack_addr)
+ return TRUE;
+ current = (guint8 *)&stack_addr;
+ if (current > stack_addr) {
+ if ((current - stack_addr) < min_size)
+ return FALSE;
+ } else {
+ if (current - (stack_addr - stack_size) < min_size)
+ return FALSE;
+ }
+ return TRUE;
+}
+
static MonoObject *
ves_icall_System_Object_MemberwiseClone (MonoObject *this)
{
}
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
ves_icall_type_from_handle (MonoType *handle)
{
MonoDomain *domain = mono_domain_get ();
- MonoClass *klass = mono_class_from_mono_type (handle);
MONO_ARCH_SAVE_REGS;
- mono_class_init (klass);
return mono_type_get_object (domain, handle);
}
return TYPECODE_SINGLE;
case MONO_TYPE_R8:
return TYPECODE_DOUBLE;
- case MONO_TYPE_VALUETYPE:
- if (type->type->data.klass->enumtype) {
- t = mono_class_enum_basetype (type->type->data.klass)->type;
+ case MONO_TYPE_VALUETYPE: {
+ MonoClass *klass = type->type->data.klass;
+
+ if (klass->enumtype) {
+ t = mono_class_enum_basetype (klass)->type;
goto handle_enum;
- } else {
- MonoClass *k = type->type->data.klass;
- if (strcmp (k->name_space, "System") == 0) {
- if (strcmp (k->name, "Decimal") == 0)
+ } else if (mono_is_corlib_image (klass->image)) {
+ if (strcmp (klass->name_space, "System") == 0) {
+ if (strcmp (klass->name, "Decimal") == 0)
return TYPECODE_DECIMAL;
- else if (strcmp (k->name, "DateTime") == 0)
+ else if (strcmp (klass->name, "DateTime") == 0)
return TYPECODE_DATETIME;
}
}
return TYPECODE_OBJECT;
+ }
case MONO_TYPE_STRING:
return TYPECODE_STRING;
case MONO_TYPE_SZARRAY:
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)
+ MonoClass *klass = type->type->data.klass;
+ if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
+ if (strcmp (klass->name, "DBNull") == 0)
return TYPECODE_DBNULL;
}
}
klass = mono_class_from_mono_type (type->type);
klassc = mono_class_from_mono_type (c->type);
+ /* Interface check requires a more complex setup so we
+ * only do for them. Otherwise we simply avoid mono_class_init.
+ */
+ if (check_interfaces) {
+ mono_class_init_or_throw (klass);
+ mono_class_init_or_throw (klassc);
+ } else if (!klass->supertypes || !klassc->supertypes) {
+ mono_loader_lock ();
+ mono_class_setup_supertypes (klass);
+ mono_class_setup_supertypes (klassc);
+ mono_loader_unlock ();
+ }
+
if (type->type->byref)
return klassc == mono_defaults.object_class;
return mono_class_is_subclass_of (klass, klassc, check_interfaces);
}
+static gboolean
+mono_type_is_primitive (MonoType *type)
+{
+ return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
+ type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
+}
+
+static MonoType*
+mono_type_get_underlying_type_ignore_byref (MonoType *type)
+{
+ if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
+ return mono_class_enum_basetype (type->data.klass);
+ if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
+ return mono_class_enum_basetype (type->data.generic_class->container_class);
+ return type;
+}
+
static guint32
ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
{
klass = mono_class_from_mono_type (type->type);
klassc = mono_class_from_mono_type (c->type);
- if (type->type->byref && !c->type->byref)
+ mono_class_init_or_throw (klass);
+ mono_class_init_or_throw (klassc);
+
+ if (type->type->byref ^ c->type->byref)
return FALSE;
+ if (type->type->byref) {
+ MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
+ MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
+
+ klass = mono_class_from_mono_type (t);
+ klassc = mono_class_from_mono_type (ot);
+
+ if (mono_type_is_primitive (t)) {
+ return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
+ } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
+ return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
+ } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
+ return t->type == ot->type;
+ } else {
+ if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
+ return FALSE;
+
+ if (klass->valuetype)
+ return klass == klassc;
+ return klass->valuetype == klassc->valuetype;
+ }
+ }
return mono_class_is_assignable_from (klass, klassc);
}
ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
{
MonoClass *klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
return mono_object_isinst (obj, klass) != NULL;
}
ves_icall_get_attributes (MonoReflectionType *type)
{
MonoClass *klass = mono_class_from_mono_type (type->type);
-
- MONO_ARCH_SAVE_REGS;
-
return klass->flags;
}
static MonoArray*
ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
{
- MonoType *type = field->field->type;
+ MonoError error;
+ MonoType *type = mono_field_get_type_checked (field->field, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
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 gint32
ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
{
+ MonoClass *parent = field->field->parent;
+ if (!parent->size_inited)
+ mono_class_init (parent);
+
return field->field->offset - sizeof (MonoObject);
}
static MonoObject *
ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
{
- MonoObject *o;
+ MonoClass *fklass = field->klass;
MonoClassField *cf = field->field;
- MonoClass *klass;
- MonoVTable *vtable;
- MonoType *t;
- MonoDomain *domain = mono_object_domain (field);
- gchar *v;
- gboolean is_static = FALSE;
- gboolean is_ref = FALSE;
-
- MONO_ARCH_SAVE_REGS;
+ MonoDomain *domain = mono_object_domain (field);
- if (field->klass->image->assembly->ref_only)
+ if (fklass->image->assembly->ref_only)
mono_raise_exception (mono_get_exception_invalid_operation (
"It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
-
+
if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
mono_security_core_clr_ensure_reflection_access_field (cf);
- mono_class_init (field->klass);
-
- if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
- is_static = TRUE;
-
- if (obj && !is_static) {
- /* Check that the field belongs to the object */
- gboolean found = FALSE;
- MonoClass *k;
-
- for (k = obj->vtable->klass; k; k = k->parent) {
- if (k == cf->parent) {
- found = TRUE;
- break;
- }
- }
-
- if (!found) {
- char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", mono_field_get_name (cf), cf->parent->name, obj->vtable->klass->name);
- MonoException *ex = mono_get_exception_argument (NULL, msg);
- g_free (msg);
- mono_raise_exception (ex);
- }
- }
-
- t = mono_type_get_underlying_type (cf->type);
- switch (t->type) {
- case MONO_TYPE_STRING:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- is_ref = TRUE;
- break;
- case MONO_TYPE_U1:
- case MONO_TYPE_I1:
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_U2:
- case MONO_TYPE_I2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_U:
- case MONO_TYPE_I:
- case MONO_TYPE_U4:
- case MONO_TYPE_I4:
- case MONO_TYPE_R4:
- case MONO_TYPE_U8:
- case MONO_TYPE_I8:
- case MONO_TYPE_R8:
- case MONO_TYPE_VALUETYPE:
- is_ref = t->byref;
- break;
- case MONO_TYPE_GENERICINST:
- if (mono_type_generic_inst_is_valuetype (t)) {
- is_ref = t->byref;
- } else {
- is_ref = TRUE;
- }
- break;
- default:
- g_error ("type 0x%x not handled in "
- "ves_icall_Monofield_GetValue", t->type);
- return NULL;
- }
-
- vtable = NULL;
- if (is_static) {
- vtable = mono_class_vtable_full (domain, cf->parent, TRUE);
- if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
- mono_runtime_class_init (vtable);
- }
-
- if (is_ref) {
- if (is_static) {
- mono_field_static_get_value (vtable, cf, &o);
- } else {
- mono_field_get_value (obj, cf, &o);
- }
- return o;
- }
-
- if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
- MonoClass *nklass = mono_class_from_mono_type (cf->type);
- guint8 *buf;
-
- /* Convert the Nullable structure into a boxed vtype */
- if (is_static)
- buf = (guint8*)vtable->data + cf->offset;
- else
- buf = (guint8*)obj + cf->offset;
-
- return mono_nullable_box (buf, nklass);
- }
-
- /* boxed value type */
- klass = mono_class_from_mono_type (cf->type);
- o = mono_object_new (domain, klass);
- v = ((gchar *) o) + sizeof (MonoObject);
- if (is_static) {
- mono_field_static_get_value (vtable, cf, v);
- } else {
- mono_field_get_value (obj, cf, v);
- }
-
- return o;
+ return mono_field_get_value_object (domain, cf, obj);
}
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);
def_value = mono_class_get_field_default_value (field, &def_type);
+ /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
switch (def_type) {
case MONO_TYPE_U1:
case MONO_TYPE_I1:
return o;
}
+static MonoReflectionType*
+ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
+{
+ MonoError error;
+ MonoClassField *field = ref_field->field;
+ MonoType *type = mono_field_get_type_checked (field, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+ return mono_type_get_object (mono_object_domain (ref_field), type);
+}
+
static MonoReflectionType*
ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
{
if ((req_info & PInfo_ReflectedType) != 0)
MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
- else if ((req_info & PInfo_DeclaringType) != 0)
- MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
+ if ((req_info & PInfo_DeclaringType) != 0)
+ MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &property->property->parent->byval_arg));
if ((req_info & PInfo_Name) != 0)
MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
MONO_STRUCT_SETREF (info, remove_method, event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL);
MONO_STRUCT_SETREF (info, raise_method, event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL);
+#ifndef MONO_SMALL_CONFIG
if (event->event->other) {
int i, n = 0;
while (event->event->other [n])
for (i = 0; i < n; i++)
mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
}
+#endif
+}
+
+static void
+collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
+{
+ int i;
+ MonoClass *ic;
+
+ mono_class_setup_interfaces (klass, error);
+ if (!mono_error_ok (error))
+ return;
+
+ for (i = 0; i < klass->interface_count; i++) {
+ ic = klass->interfaces [i];
+ g_hash_table_insert (ifaces, ic, ic);
+
+ collect_interfaces (ic, ifaces, error);
+ if (!mono_error_ok (error))
+ return;
+ }
+}
+
+typedef struct {
+ MonoArray *iface_array;
+ MonoGenericContext *context;
+ MonoError *error;
+ MonoDomain *domain;
+ int next_idx;
+} FillIfaceArrayData;
+
+static void
+fill_iface_array (gpointer key, gpointer value, gpointer user_data)
+{
+ FillIfaceArrayData *data = user_data;
+ MonoClass *ic = key;
+ MonoType *ret = &ic->byval_arg, *inflated = NULL;
+
+ if (!mono_error_ok (data->error))
+ return;
+
+ if (data->context && ic->generic_class && ic->generic_class->context.class_inst->is_open) {
+ inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
+ if (!mono_error_ok (data->error))
+ return;
+ }
+
+ mono_array_setref (data->iface_array, data->next_idx++, mono_type_get_object (data->domain, ret));
+
+ if (inflated)
+ mono_metadata_free_type (inflated);
}
static MonoArray*
ves_icall_Type_GetInterfaces (MonoReflectionType* type)
{
MonoError error;
- MonoDomain *domain = mono_object_domain (type);
- MonoArray *intf;
- GPtrArray *ifaces = NULL;
- int i;
MonoClass *class = mono_class_from_mono_type (type->type);
MonoClass *parent;
- MonoBitSet *slots;
- MonoGenericContext *context = NULL;
+ FillIfaceArrayData data = { 0 };
+ int len;
- MONO_ARCH_SAVE_REGS;
+ GHashTable *iface_hash = g_hash_table_new (NULL, NULL);
if (class->generic_class && class->generic_class->context.class_inst->is_open) {
- context = mono_class_get_context (class);
+ data.context = mono_class_get_context (class);
class = class->generic_class->container_class;
}
- mono_class_setup_vtable (class);
-
- slots = mono_bitset_new (class->max_interface_id + 1, 0);
-
for (parent = class; parent; parent = parent->parent) {
- GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent, &error);
- if (!mono_error_ok (&error)) {
- mono_bitset_free (slots);
- mono_error_raise_exception (&error);
- return NULL;
- } else if (tmp_ifaces) {
- for (i = 0; i < tmp_ifaces->len; ++i) {
- MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
+ mono_class_setup_interfaces (parent, &error);
+ if (!mono_error_ok (&error))
+ goto fail;
+ collect_interfaces (parent, iface_hash, &error);
+ if (!mono_error_ok (&error))
+ goto fail;
+ }
- if (mono_bitset_test (slots, ic->interface_id))
- continue;
+ data.error = &error;
+ data.domain = mono_object_domain (type);
- mono_bitset_set (slots, ic->interface_id);
- if (ifaces == NULL)
- ifaces = g_ptr_array_new ();
- g_ptr_array_add (ifaces, ic);
- }
- g_ptr_array_free (tmp_ifaces, TRUE);
- }
+ len = g_hash_table_size (iface_hash);
+ if (len == 0) {
+ g_hash_table_destroy (iface_hash);
+ if (!data.domain->empty_types)
+ data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.monotype_class, 0);
+ return data.domain->empty_types;
}
- mono_bitset_free (slots);
- if (!ifaces)
- return mono_array_new_cached (domain, mono_defaults.monotype_class, 0);
-
- intf = mono_array_new_cached (domain, mono_defaults.monotype_class, ifaces->len);
- for (i = 0; i < ifaces->len; ++i) {
- MonoClass *ic = g_ptr_array_index (ifaces, i);
- MonoType *ret = &ic->byval_arg, *inflated = NULL;
- if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
- inflated = ret = mono_class_inflate_generic_type (ret, context);
-
- mono_array_setref (intf, i, mono_type_get_object (domain, ret));
- if (inflated)
- mono_metadata_free_type (inflated);
- }
- g_ptr_array_free (ifaces, TRUE);
+ data.iface_array = mono_array_new_cached (data.domain, mono_defaults.monotype_class, len);
+ g_hash_table_foreach (iface_hash, fill_iface_array, &data);
+ if (!mono_error_ok (&error))
+ goto fail;
- return intf;
+ g_hash_table_destroy (iface_hash);
+ return data.iface_array;
+
+fail:
+ g_hash_table_destroy (iface_hash);
+ mono_error_raise_exception (&error);
+ return NULL;
}
static void
MonoDomain *domain;
MONO_ARCH_SAVE_REGS;
+ mono_class_init_or_throw (class);
+ mono_class_init_or_throw (iclass);
mono_class_setup_vtable (class);
ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
{
MonoClass *klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
if (klass->image->dynamic) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
return mono_type_get_object (mono_object_domain (type), &type->type->data.klass->byval_arg);
class = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (class);
// GetElementType should only return a type for:
// Array Pointer PassedByRef
ves_icall_get_type_parent (MonoReflectionType *type)
{
MonoClass *class = mono_class_from_mono_type (type->type);
-
- MONO_ARCH_SAVE_REGS;
-
return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
}
ves_icall_type_iscomobject (MonoReflectionType *type)
{
MonoClass *klass = mono_class_from_mono_type (type->type);
- MONO_ARCH_SAVE_REGS;
+ mono_class_init_or_throw (klass);
return (klass && klass->is_com_object);
}
ves_icall_MonoType_get_Module (MonoReflectionType *type)
{
MonoClass *class = mono_class_from_mono_type (type->type);
-
- MONO_ARCH_SAVE_REGS;
-
return mono_module_get_object (mono_object_domain (type), class->image);
}
{
MonoDomain *domain = mono_domain_get ();
MonoClass *class = mono_class_from_mono_type (type->type);
-
- MONO_ARCH_SAVE_REGS;
-
return mono_assembly_get_object (domain, class->image->assembly);
}
return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
}
-static MonoReflectionType*
-ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
-{
- MonoDomain *domain = mono_domain_get ();
- MonoClass *class = mono_class_from_mono_type (type->type);
-
- MONO_ARCH_SAVE_REGS;
-
- if (class->enumtype && mono_class_enum_basetype (class)) /* types that are modified typebuilders may not have enum_basetype set */
- return mono_type_get_object (domain, mono_class_enum_basetype (class));
- else if (class->element_class)
- return mono_type_get_object (domain, &class->element_class->byval_arg);
- else
- return NULL;
-}
-
static MonoString*
ves_icall_MonoType_get_Name (MonoReflectionType *type)
{
MonoDomain *domain = mono_domain_get ();
MonoClass *class = mono_class_from_mono_type (type->type);
- MONO_ARCH_SAVE_REGS;
-
if (type->type->byref) {
char *n = g_strdup_printf ("%s&", class->name);
MonoString *res = mono_string_new (domain, n);
MonoDomain *domain = mono_domain_get ();
MonoClass *class = mono_class_from_mono_type (type->type);
- MONO_ARCH_SAVE_REGS;
-
while (class->nested_in)
class = class->nested_in;
mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type"));
class = mono_class_from_mono_type (type->type);
+
return class->rank;
}
return FALSE;
klass = mono_class_from_mono_type (type->type);
-
return klass->generic_container != NULL;
}
return NULL;
klass = mono_class_from_mono_type (type->type);
+
if (klass->generic_container) {
return type; /* check this one */
}
if (klass->generic_class) {
MonoClass *generic_class = klass->generic_class->container_class;
+ gpointer tb;
- if (generic_class->wastypebuilder && generic_class->reflection_info)
- return generic_class->reflection_info;
+ tb = mono_class_get_ref_info (generic_class);
+
+ if (generic_class->wastypebuilder && tb)
+ return tb;
else
return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
}
MonoType *geninst, **types;
int i, count;
- MONO_ARCH_SAVE_REGS;
+ g_assert (IS_MONOTYPE (type));
+ mono_class_init_or_throw (mono_class_from_mono_type (type->type));
count = mono_array_length (type_array);
types = g_new0 (MonoType *, count);
return FALSE;
klass = mono_class_from_mono_type (type->type);
+
return klass->generic_class != NULL;
}
domain = ((MonoObject *)type)->vtable->domain;
klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
iter = NULL;
while ((method = mono_class_get_methods (klass, &iter))) {
mono_security_core_clr_ensure_reflection_access_method (m);
if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
+ if (!mono_class_vtable_full (mono_object_domain (method), m->klass, FALSE)) {
+ mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
+ return NULL;
+ }
+
if (this) {
if (!mono_object_isinst (this, m->klass)) {
mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type."));
if (m->klass->rank && !strcmp (m->name, ".ctor")) {
int i;
- mono_array_size_t *lengths;
- mono_array_size_t *lower_bounds;
+ uintptr_t *lengths;
+ intptr_t *lower_bounds;
pcount = mono_array_length (params);
- lengths = alloca (sizeof (mono_array_size_t) * pcount);
+ lengths = alloca (sizeof (uintptr_t) * pcount);
+ /* Note: the synthetized array .ctors have int32 as argument type */
for (i = 0; i < pcount; ++i)
- lengths [i] = *(mono_array_size_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
+ lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
if (m->klass->rank == pcount) {
/* Only lengths provided. */
} else {
g_assert (pcount == (m->klass->rank * 2));
/* lower bounds are first. */
- lower_bounds = lengths;
+ lower_bounds = (intptr_t*)lengths;
lengths += m->klass->rank;
}
MonoDomain *domain;
MonoClass *enumc, *objc;
MonoObject *res;
+ MonoType *etype;
guint64 val;
MONO_ARCH_SAVE_REGS;
domain = mono_object_domain (enumType);
enumc = mono_class_from_mono_type (enumType->type);
+
+ mono_class_init_or_throw (enumc);
+
objc = value->vtable->klass;
if (!enumc->enumtype)
if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
mono_raise_exception (mono_get_exception_argument ("value", "The value passed in must be an enum base or an underlying type for an enum, such as an Int32."));
+ etype = mono_class_enum_basetype (enumc);
+ if (!etype)
+ /* MS throws this for typebuilders */
+ mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
+
res = mono_object_new (domain, enumc);
val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? mono_class_enum_basetype (objc)->type: objc->byval_arg.type);
- write_enum_value ((char *)res + sizeof (MonoObject), mono_class_enum_basetype (enumc)->type, val);
+ write_enum_value ((char *)res + sizeof (MonoObject), etype->type, val);
return res;
}
static MonoReflectionType *
ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
{
+ MonoType *etype;
+ MonoClass *klass;
+
MONO_ARCH_SAVE_REGS;
- return mono_type_get_object (mono_object_domain (type), mono_class_enum_basetype (mono_class_from_mono_type (type->type)));
+ klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+
+ etype = mono_class_enum_basetype (klass);
+ if (!etype)
+ /* MS throws this for typebuilders */
+ mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
+
+ return mono_type_get_object (mono_object_domain (type), etype);
}
static int
MONO_ARCH_SAVE_REGS;
+ mono_class_init_or_throw (enumc);
+
MONO_STRUCT_SETREF (info, utype, mono_type_get_object (domain, mono_class_enum_basetype (enumc)));
nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
MONO_STRUCT_SETREF (info, names, mono_array_new (domain, mono_defaults.string_class, nvalues));
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))
domain = ((MonoObject *)type)->vtable->domain;
klass = startklass = mono_class_from_mono_type (type->type);
- MONO_ARCH_SAVE_REGS;
-
if (!name)
mono_raise_exception (mono_get_exception_argument_null ("name"));
if (type->type->byref)
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++;
mono_ptr_array_init (tmp_array, 2);
handle_parent:
- if (klass->exception_type != MONO_EXCEPTION_NONE)
+ if (klass->exception_type != MONO_EXCEPTION_NONE) {
+ mono_ptr_array_destroy (tmp_array);
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 (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++;
MonoException *ex;
MonoPtrArray tmp_array;
- MONO_ARCH_SAVE_REGS;
-
mono_ptr_array_init (tmp_array, 4);
if (!MethodInfo_array) {
return mono_array_new_specific (array_vtable, 0);
klass = startklass = mono_class_from_mono_type (type->type);
refklass = mono_class_from_mono_type (reftype->type);
+
len = 0;
if (name != NULL) {
mname = mono_string_to_utf8 (name);
klass = startklass = mono_class_from_mono_type (type->type);
refklass = mono_class_from_mono_type (reftype->type);
- if (klass->exception_type != MONO_EXCEPTION_NONE)
- mono_raise_exception (mono_class_get_exception_for_failure (klass));
-
if (!System_Reflection_ConstructorInfo)
System_Reflection_ConstructorInfo = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
static MonoArray*
ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
{
+ MonoException *ex;
MonoDomain *domain;
static MonoClass *System_Reflection_PropertyInfo;
MonoClass *startklass, *klass;
gchar *propname = NULL;
int (*compare_func) (const char *s1, const char *s2) = NULL;
gpointer iter;
- GHashTable *properties;
+ GHashTable *properties = NULL;
MonoPtrArray tmp_array;
MONO_ARCH_SAVE_REGS;
if (type->type->byref)
return mono_array_new_cached (domain, System_Reflection_PropertyInfo, 0);
klass = startklass = mono_class_from_mono_type (type->type);
+
if (name != NULL) {
propname = mono_string_to_utf8 (name);
compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
}
- mono_class_setup_vtable (klass);
-
properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
handle_parent:
mono_class_setup_vtable (klass);
- if (klass->exception_type != MONO_EXCEPTION_NONE) {
- g_hash_table_destroy (properties);
- if (name != NULL)
- g_free (propname);
- mono_raise_exception (mono_class_get_exception_for_failure (klass));
- }
+ if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+ goto loader_error;
iter = NULL;
while ((prop = mono_class_get_properties (klass, &iter))) {
mono_ptr_array_destroy (tmp_array);
return res;
+
+loader_error:
+ if (properties)
+ g_hash_table_destroy (properties);
+ if (name)
+ g_free (propname);
+ mono_ptr_array_destroy (tmp_array);
+
+ if (klass->exception_type != MONO_EXCEPTION_NONE) {
+ ex = mono_class_get_exception_for_failure (klass);
+ } else {
+ ex = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+ mono_loader_clear_error ();
+ }
+ mono_raise_exception (ex);
+ return NULL;
}
static MonoReflectionEvent *
MonoEvent *event;
MonoMethod *method;
gchar *event_name;
+ int (*compare_func) (const char *s1, const char *s2);
MONO_ARCH_SAVE_REGS;
klass = startklass = mono_class_from_mono_type (type->type);
domain = mono_object_domain (type);
+ mono_class_init_or_throw (klass);
+
+ compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
handle_parent:
if (klass->exception_type != MONO_EXCEPTION_NONE)
mono_raise_exception (mono_class_get_exception_for_failure (klass));
iter = NULL;
while ((event = mono_class_get_events (klass, &iter))) {
- if (strcmp (event->name, event_name))
+ if (compare_func (event->name, event_name))
continue;
method = event->add;
static MonoArray*
ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
{
+ MonoException *ex;
MonoDomain *domain;
static MonoClass *System_Reflection_EventInfo;
MonoClass *startklass, *klass;
return mono_array_new_cached (domain, System_Reflection_EventInfo, 0);
klass = startklass = mono_class_from_mono_type (type->type);
-handle_parent:
- if (klass->exception_type != MONO_EXCEPTION_NONE)
- mono_raise_exception (mono_class_get_exception_for_failure (klass));
+handle_parent:
+ mono_class_setup_vtable (klass);
+ if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+ goto loader_error;
iter = NULL;
while ((event = mono_class_get_events (klass, &iter))) {
mono_ptr_array_destroy (tmp_array);
return res;
+
+loader_error:
+ mono_ptr_array_destroy (tmp_array);
+ if (klass->exception_type != MONO_EXCEPTION_NONE) {
+ ex = mono_class_get_exception_for_failure (klass);
+ } else {
+ ex = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+ mono_loader_clear_error ();
+ }
+ mono_raise_exception (ex);
+ return NULL;
}
static MonoReflectionType *
if (type->type->byref)
return NULL;
klass = mono_class_from_mono_type (type->type);
+
str = mono_string_to_utf8 (name);
handle_parent:
if (type->type->byref)
return mono_array_new (domain, mono_defaults.monotype_class, 0);
klass = mono_class_from_mono_type (type->type);
- if (klass->exception_type != MONO_EXCEPTION_NONE)
- mono_raise_exception (mono_class_get_exception_for_failure (klass));
/*
* If a nested type is generic, return its generic type definition.
mono_raise_exception (e);
return NULL;
+ } else if (mono_loader_get_last_error ()) {
+ if (throwOnError)
+ mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+ mono_loader_clear_error ();
}
if (type->type == MONO_TYPE_CLASS) {
MonoString *res;
gchar *name;
- MONO_ARCH_SAVE_REGS;
if (full_name)
format = assembly_qualified ?
MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
return res;
}
+static int
+vell_icall_MonoType_get_core_clr_security_level (MonoReflectionType *this)
+{
+ MonoClass *klass = mono_class_from_mono_type (this->type);
+ mono_class_init_or_throw (klass);
+ return mono_security_core_clr_class_level (klass);
+}
+
static void
fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
{
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);
if (g_path_is_absolute (mass->image->name)) {
fill_reflection_assembly_name (mono_object_domain (assembly),
aname, &mass->aname, mass->image->name, TRUE,
- TRUE, mono_framework_version () >= 2);
+ TRUE, TRUE);
return;
}
absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
fill_reflection_assembly_name (mono_object_domain (assembly),
aname, &mass->aname, absolute, TRUE, TRUE,
- mono_framework_version () >= 2);
+ TRUE);
g_free (absolute);
}
}
fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
- TRUE, mono_framework_version () == 1,
- mono_framework_version () >= 2);
+ TRUE, FALSE, TRUE);
g_free (filename);
mono_image_close (image);
}
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);
return res;
}
+static void
+check_for_invalid_type (MonoClass *klass)
+{
+ char *name;
+ MonoString *str;
+ if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
+ return;
+
+ name = mono_type_get_full_name (klass);
+ str = mono_string_new (mono_domain_get (), name);
+ g_free (name);
+ mono_raise_exception ((MonoException*)mono_get_exception_type_load (str, NULL));
+
+}
static MonoReflectionType *
ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
{
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type);
+ check_for_invalid_type (klass);
+
if (rank == 0) //single dimentional array
aklass = mono_array_class_get (klass, 1);
else
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+ check_for_invalid_type (klass);
return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
}
static MonoReflectionType *
ves_icall_Type_MakePointerType (MonoReflectionType *type)
{
- MonoClass *pklass;
+ MonoClass *klass, *pklass;
- MONO_ARCH_SAVE_REGS;
+ klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+ check_for_invalid_type (klass);
pklass = mono_ptr_class_get (type->type);
MONO_ARCH_SAVE_REGS;
+ mono_class_init_or_throw (delegate_class);
+
mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
return 2;
#elif defined(__MACH__)
/* OSX */
- if (mono_framework_version () < 2)
- return 128;
-
//
// 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
return 4;
#else
/* Unix */
- if (mono_framework_version () < 2)
- return 128;
return 4;
#endif
}
*/
#ifndef _MSC_VER
#ifndef __MINGW32_VERSION
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined (__arm__)
/* Apple defines this in crt_externs.h but doesn't provide that header for
* arm-apple-darwin9. We'll manually define the symbol on Apple as it does
* in fact exist on all implementations (so far)
mono_runtime_set_shutting_down ();
+ /* This will kill the tp threads which cannot be suspended */
+ mono_thread_pool_cleanup ();
+
/* Suspend all managed threads since the runtime is going away */
mono_thread_suspend_all_other_threads ();
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;
method = rmethod->method;
klass = mono_class_from_mono_type (rtype->type);
+ mono_class_init_or_throw (klass);
if (MONO_CLASS_IS_INTERFACE (klass))
return NULL;
domain = mono_object_domain (type);
klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
if (klass->rank >= 1) {
g_assert (klass->rank == 1);
return mcpath;
}
+static MonoString *
+get_bundled_app_config (void)
+{
+ const gchar *app_config;
+ MonoDomain *domain;
+ MonoString *file;
+ gchar *config_file;
+ gsize len;
+ gchar *module;
+
+ MONO_ARCH_SAVE_REGS;
+
+ domain = mono_domain_get ();
+ file = domain->setup->configuration_file;
+ if (!file)
+ return NULL;
+
+ // Retrieve config file and remove the extension
+ config_file = mono_string_to_utf8 (file);
+ len = strlen (config_file) - strlen (".config");
+ module = g_malloc0 (len + 1);
+ memcpy (module, config_file, 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 (!app_config)
+ return NULL;
+
+ return mono_string_new (mono_domain_get (), app_config);
+}
+
static MonoString *
get_bundled_machine_config (void)
{
domain = mono_object_domain (type);
klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
if (mono_class_is_nullable (klass))
/* No arguments -> null */
if (klass == method->klass)
return m;
+ /*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)
+ return m;
+
result = klass->vtable [method->slot];
if (result == NULL) {
/* It is an abstract method */
gpointer iter = NULL;
MONO_ARCH_SAVE_REGS;
+ mono_class_init_or_throw (klass);
+
while ((m = mono_class_get_methods (klass, &iter)))
prelink_method (m);
}
return type_array_from_modifiers (image, type, optional);
}
+/*
+ *Construct a MonoType suited to be used to decode a constant blob object.
+ *
+ * @type is the target type which will be constructed
+ * @blob_type is the blob type, for example, that comes from the constant table
+ * @real_type is the expected constructed type.
+ */
+static void
+mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
+{
+ type->type = blob_type;
+ type->data.klass = NULL;
+ if (blob_type == MONO_TYPE_CLASS)
+ type->data.klass = mono_defaults.object_class;
+ else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
+ /* For enums, we need to use the base type */
+ type->type = MONO_TYPE_VALUETYPE;
+ type->data.klass = mono_class_from_mono_type (real_type);
+ } else
+ type->data.klass = mono_class_from_mono_type (real_type);
+}
+
+static MonoObject*
+property_info_get_default_value (MonoReflectionProperty *property)
+{
+ MonoType blob_type;
+ MonoProperty *prop = property->property;
+ MonoType *type = get_property_type (prop);
+ MonoDomain *domain = mono_object_domain (property);
+ MonoTypeEnum def_type;
+ const char *def_value;
+ MonoObject *o;
+
+ mono_class_init (prop->parent);
+
+ if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT))
+ mono_raise_exception (mono_get_exception_invalid_operation (NULL));
+
+ def_value = mono_class_get_property_default_value (prop, &def_type);
+
+ mono_type_from_blob_type (&blob_type, def_type, type);
+ o = mono_get_object_from_blob (domain, &blob_type, def_value);
+
+ return o;
+}
+
static MonoBoolean
custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
{
+ MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
MonoCustomAttrInfo *cinfo;
gboolean found;
+ mono_class_init_or_throw (attr_class);
+
cinfo = mono_reflection_get_custom_attrs_info (obj);
if (!cinfo)
return FALSE;
- found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
+ found = mono_custom_attrs_has_attr (cinfo, attr_class);
if (!cinfo->cached)
mono_custom_attrs_free (cinfo);
return found;
static MonoArray*
custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
{
- MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
+ MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
+ MonoArray *res;
+
+ if (attr_class)
+ mono_class_init_or_throw (attr_class);
+
+ res = mono_reflection_get_custom_attrs_by_type (obj, attr_class);
if (mono_loader_get_last_error ()) {
mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));