#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>
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
*/
static MonoArray *
ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
{
- MonoClass *aklass;
+ MonoClass *aklass, *klass;
MonoArray *array;
uintptr_t *sizes, i;
gboolean bounded = FALSE;
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(intptr_t) * 2);
for (i = 0; i < aklass->rank; ++i) {
static MonoArray *
ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
{
- MonoClass *aklass;
+ MonoClass *aklass, *klass;
MonoArray *array;
uintptr_t *sizes, i;
gboolean bounded = FALSE;
(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(intptr_t) * 2);
for (i = 0; i < aklass->rank; ++i) {
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);
}
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 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
#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);
- }
- }
- mono_bitset_free (slots);
+ len = g_hash_table_size (iface_hash);
+ if (len == 0)
+ return mono_array_new_cached (data.domain, mono_defaults.monotype_class, 0);
- 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;
+
+ g_hash_table_destroy (iface_hash);
+ return data.iface_array;
- return intf;
+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;
+ mono_class_init_or_throw (class);
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;
+ mono_class_init_or_throw (class);
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);
+ 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 FALSE;
klass = mono_class_from_mono_type (type->type);
-
return klass->generic_container != NULL;
}
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 */
}
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."));
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 (*compare_func) (const char *s1, const char *s2) = NULL;
domain = ((MonoObject *)type)->vtable->domain;
klass = startklass = mono_class_from_mono_type (type->type);
-
- MONO_ARCH_SAVE_REGS;
+ mono_class_init_or_throw (klass);
if (!name)
mono_raise_exception (mono_get_exception_argument_null ("name"));
klass = startklass = mono_class_from_mono_type (type->type);
refklass = mono_class_from_mono_type (reftype->type);
+ mono_class_init_or_throw (klass);
+ mono_class_init_or_throw (refklass);
+
mono_ptr_array_init (tmp_array, 2);
handle_parent:
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);
+
+ mono_class_init_or_throw (klass);
+ mono_class_init_or_throw (refklass);
+
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);
+ mono_class_init_or_throw (klass);
+ mono_class_init_or_throw (refklass);
+
if (klass->exception_type != MONO_EXCEPTION_NONE)
mono_raise_exception (mono_class_get_exception_for_failure (klass));
if (type->type->byref)
return mono_array_new_cached (domain, System_Reflection_PropertyInfo, 0);
klass = startklass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+
+
+
if (name != NULL) {
propname = mono_string_to_utf8 (name);
compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
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;
if (type->type->byref)
return mono_array_new_cached (domain, System_Reflection_EventInfo, 0);
klass = startklass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+
handle_parent:
if (klass->exception_type != MONO_EXCEPTION_NONE)
if (type->type->byref)
return NULL;
klass = mono_class_from_mono_type (type->type);
+ mono_class_init_or_throw (klass);
+
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));
+ mono_class_init_or_throw (klass);
/*
* If a nested type is generic, return its generic type definition.
MonoString *res;
gchar *name;
- MONO_ARCH_SAVE_REGS;
if (full_name)
format = assembly_qualified ?
MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
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);
}
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);
+ mono_class_init_or_throw (klass);
+ 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) {
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 ();
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);
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 */
gpointer iter = NULL;
MONO_ARCH_SAVE_REGS;
+ mono_class_init_or_throw (klass);
+
while ((m = mono_class_get_methods (klass, &iter)))
prelink_method (m);
}
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 ()));