#include <stdarg.h>
#include <string.h>
#include <ctype.h>
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#if defined (PLATFORM_WIN32)
#include <stdlib.h>
#endif
#include <mono/metadata/class-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/gc-internal.h>
+#include <mono/metadata/mono-gc.h>
#include <mono/metadata/rand.h>
#include <mono/metadata/sysmath.h>
#include <mono/metadata/string-icalls.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/cil-coff.h>
#include <mono/metadata/security-manager.h>
+#include <mono/metadata/security-core-clr.h>
#include <mono/io-layer/io-layer.h>
#include <mono/utils/strtod.h>
#include <mono/utils/monobitset.h>
static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
+static MonoArray*
+type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
static inline MonoBoolean
is_generic_parameter (MonoType *type)
*result = strtod (ptr, &endptr);
#else
if (*ptr)
- *result = bsd_strtod (ptr, &endptr);
+ *result = mono_strtod (ptr, &endptr);
#endif
if (!*ptr || (endptr && *endptr))
return NULL;
}
-static void
-ves_icall_System_Double_AssertEndianity (double *value)
-{
- MONO_ARCH_SAVE_REGS;
-
- MONO_DOUBLE_ASSERT_ENDIANITY (value);
-}
-
static MonoObject *
ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
{
MonoClass *ac, *vc, *ec;
gint32 esize, vsize;
gpointer *ea, *va;
+ int et, vt;
guint64 u64 = 0;
gint64 i64 = 0;
vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
+ et = ec->byval_arg.type;
+ if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
+ et = ec->byval_arg.data.klass->enum_basetype->type;
+
+ vt = vc->byval_arg.type;
+ if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
+ vt = vc->byval_arg.data.klass->enum_basetype->type;
+
#define ASSIGN_UNSIGNED(etype) G_STMT_START{\
- switch (vc->byval_arg.type) { \
+ switch (vt) { \
case MONO_TYPE_U1: \
case MONO_TYPE_U2: \
case MONO_TYPE_U4: \
}G_STMT_END
#define ASSIGN_SIGNED(etype) G_STMT_START{\
- switch (vc->byval_arg.type) { \
+ switch (vt) { \
case MONO_TYPE_I1: \
case MONO_TYPE_I2: \
case MONO_TYPE_I4: \
}G_STMT_END
#define ASSIGN_REAL(etype) G_STMT_START{\
- switch (vc->byval_arg.type) { \
+ switch (vt) { \
case MONO_TYPE_R4: \
case MONO_TYPE_R8: \
CHECK_WIDENING_CONVERSION(0); \
} \
}G_STMT_END
- switch (vc->byval_arg.type) {
+ switch (vt) {
case MONO_TYPE_U1:
u64 = *(guint8 *) va;
break;
break;
case MONO_TYPE_BOOLEAN:
/* Boolean is only compatible with itself. */
- switch (ec->byval_arg.type) {
+ switch (et) {
case MONO_TYPE_CHAR:
case MONO_TYPE_U1:
case MONO_TYPE_U2:
}
/* If we can't do a direct copy, let's try a widening conversion. */
- switch (ec->byval_arg.type) {
+ switch (et) {
case MONO_TYPE_CHAR:
ASSIGN_UNSIGNED (guint16);
case MONO_TYPE_U1:
}
static void
-ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
+ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
{
- MonoClass *klass = array->obj.vtable->klass;
- guint32 size = mono_array_element_size (klass);
- int i;
+ MonoClass *ac;
+ MonoArray *ao;
+ gint32 esize;
+ gpointer *ea;
MONO_ARCH_SAVE_REGS;
- if (array->bounds == NULL)
- size *= array->max_length;
- else
- for (i = 0; i < klass->rank; ++i)
- size *= array->bounds [i].length;
+ ao = (MonoArray *)this;
+ ac = (MonoClass *)ao->obj.vtable->klass;
- memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
+ esize = mono_array_element_size (ac);
+ ea = (gpointer*)((char*)ao->vector + (pos * esize));
+
+ memcpy (ea, value, esize);
+}
+
+static void
+ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
+{
+ MonoClass *klass = array->obj.vtable->klass;
+ guint32 size = mono_array_element_size (klass);
+
+ size *= array->max_length;
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
#define SWAP(n) {\
- gint i; \
- guint ## n tmp; \
guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
+ guint ## n *src = (guint ## n *) field_handle->data; \
+ guint ## n *end = (guint ## n *)((char*)src + size); \
\
- for (i = 0; i < size; i += n/8, data++) { \
- tmp = read ## n (data); \
- *data = tmp; \
+ for (; src < end; data++, src++) { \
+ *data = read ## n (src); \
} \
}
break;
case MONO_TYPE_I4:
case MONO_TYPE_U4:
+ case MONO_TYPE_R4:
SWAP (32);
break;
case MONO_TYPE_I8:
case MONO_TYPE_U8:
+ case MONO_TYPE_R8:
SWAP (64);
break;
+ default:
+ memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
+ break;
+ }
+#else
+ memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
+#ifdef ARM_FPU_FPA
+ if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
+ gint i;
+ double tmp;
+ double *data = (double*)mono_array_addr (array, double, 0);
+
+ for (i = 0; i < size; i++, data++) {
+ readr8 (data, &tmp);
+ *data = tmp;
+ }
}
-
+#endif
#endif
}
mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
}
+static void
+ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ mono_image_check_for_module_cctor (image);
+ if (image->has_module_cctor) {
+ MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
+ mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
+ }
+}
+
static MonoObject *
ves_icall_System_Object_MemberwiseClone (MonoObject *this)
{
/* mono_reflection_parse_type() mangles the string */
if (!mono_reflection_parse_type (temp_str, &info)) {
- g_list_free (info.modifiers);
- g_list_free (info.nested);
+ mono_reflection_free_type_info (&info);
g_free (temp_str);
return NULL;
}
if (!info.assembly.name && !type) /* try mscorlib */
type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
- g_list_free (info.modifiers);
- g_list_free (info.nested);
+ mono_reflection_free_type_info (&info);
g_free (temp_str);
if (!type)
type = type_from_name (str, ignoreCase);
g_free (str);
if (type == NULL){
+ MonoException *e = NULL;
+
if (throwOnError)
- mono_raise_exception (mono_get_exception_type_load (name, NULL));
+ e = mono_get_exception_type_load (name, NULL);
+
+ mono_loader_clear_error ();
+ if (e != NULL)
+ mono_raise_exception (e);
}
return type;
}
static MonoBoolean
-ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
+ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
{
MONO_ARCH_SAVE_REGS;
int i;
if (klass->generic_container ||
- (klass->generic_class && klass->generic_class->inst->is_open))
+ (klass->generic_class && klass->generic_class->context.class_inst->is_open))
return NULL;
info = mono_marshal_load_type_info (klass);
return NULL;
}
+static MonoReflectionField*
+ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
+{
+ g_assert (handle);
+
+ if (!klass)
+ klass = handle->parent;
+
+ /* FIXME: check that handle is a field of klass or of a parent: return null
+ * and throw the exception in managed code.
+ */
+ return mono_field_get_object (mono_domain_get (), klass, handle);
+}
+
static MonoReflectionField*
ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
{
return mono_field_get_object (mono_domain_get (), handle->parent, handle);
}
+static MonoArray*
+ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
+{
+ MonoType *type = field->field->type;
+
+ return type_array_from_modifiers (field->field->parent->image, type, optional);
+}
+
static void
ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
{
MonoMethodSignature* sig;
MONO_ARCH_SAVE_REGS;
- if (method->is_inflated)
- method = mono_get_inflated_method (method);
-
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 ()));
+ }
info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
info->ret = mono_type_get_object (domain, sig->ret);
{
MonoDomain *domain = mono_domain_get ();
- MONO_ARCH_SAVE_REGS;
-
- if (method->is_inflated)
- method = mono_get_inflated_method (method);
-
return mono_param_get_objects (domain, method);
}
MonoMarshalSpec **mspecs;
int i;
- MONO_ARCH_SAVE_REGS;
-
- if (method->is_inflated)
- method = mono_get_inflated_method (method);
-
mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
mono_method_get_marshal_info (method, mspecs);
break;
case MONO_TYPE_GENERICINST: {
MonoGenericClass *gclass = cf->type->data.generic_class;
- g_assert (!gclass->inst->is_open);
+ 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);
- guint8 *buf;
+ MonoObject *nullable;
/*
* Convert the boxed vtype into a Nullable structure.
* This is complicated by the fact that Nullables have
* a variable structure.
*/
- /* Allocate using alloca so it gets GC tracking */
- buf = alloca (nklass->instance_size);
+ nullable = mono_object_new (mono_domain_get (), nklass);
- mono_nullable_init (buf, value, nklass);
+ mono_nullable_init (mono_object_unbox (nullable), value, nklass);
- v = (gchar*)buf;
+ v = mono_object_unbox (nullable);
}
else
if (gclass->container_class->valuetype && (v != NULL))
static MonoReflectionType*
ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
{
- MonoMethod *method = mono_get_inflated_method (rmethod->method.method);
+ MonoMethod *method = rmethod->method.method;
return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
}
if ((req_info & PInfo_GetMethod) != 0)
info->get = property->property->get ?
- mono_method_get_object (domain, property->property->get, NULL): NULL;
+ mono_method_get_object (domain, property->property->get, property->klass): NULL;
if ((req_info & PInfo_SetMethod) != 0)
info->set = property->property->set ?
- mono_method_get_object (domain, property->property->set, NULL): NULL;
+ mono_method_get_object (domain, property->property->set, property->klass): NULL;
/*
* There may be other methods defined for properties, though, it seems they are not exposed
* in the reflection API
MONO_ARCH_SAVE_REGS;
- /* open generic-instance classes can share their interface_id */
- if (class->generic_class && class->generic_class->inst->is_open) {
- context = class->generic_class->context;
+ if (class->generic_class && class->generic_class->context.class_inst->is_open) {
+ context = mono_class_get_context (class);
class = class->generic_class->container_class;
}
for (i = 0; i < ifaces->len; ++i) {
MonoClass *ic = g_ptr_array_index (ifaces, i);
MonoType *ret = &ic->byval_arg;
- if (context && ic->generic_class && ic->generic_class->inst->is_open)
+ if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
ret = mono_class_inflate_generic_type (ret, context);
mono_array_setref (intf, i, mono_type_get_object (domain, ret));
mono_class_setup_vtable (class);
/* type doesn't implement iface: the exception is thrown in managed code */
- if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
+ if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
return;
len = mono_class_num_methods (iclass);
- ioffset = class->interface_offsets [iclass->interface_id];
+ ioffset = mono_class_interface_offset (class, iclass);
domain = mono_object_domain (type);
*targets = mono_array_new (domain, mono_defaults.method_info_class, len);
*methods = mono_array_new (domain, mono_defaults.method_info_class, len);
if (type->type->byref)
return NULL;
if (type->type->type == MONO_TYPE_VAR)
- class = type->type->data.generic_param->owner->klass;
+ class = type->type->data.generic_param->owner->owner.klass;
else if (type->type->type == MONO_TYPE_MVAR)
- class = type->type->data.generic_param->method->klass;
+ class = type->type->data.generic_param->owner->owner.method->klass;
else
class = mono_class_from_mono_type (type->type)->nested_in;
if (klass->generic_container) {
MonoGenericContainer *container = klass->generic_container;
- res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
+ res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
for (i = 0; i < container->type_argc; ++i) {
pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
}
} else if (klass->generic_class) {
- MonoGenericInst *inst = klass->generic_class->inst;
- res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
+ MonoGenericInst *inst = klass->generic_class->context.class_inst;
+ res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
for (i = 0; i < inst->type_argc; ++i)
mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
} else {
- res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
+ res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
}
return res;
}
}
geninst = mono_reflection_bind_generic_parameters (type, count, types);
+ g_free (types);
if (!geninst)
return NULL;
return NULL;
inflated = mono_class_inflate_generic_type (
- parent->type, gclass->generic_class.generic_class.context);
+ parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
return mono_type_get_object (domain, inflated);
}
ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
{
static MonoClass *System_Reflection_MonoGenericClass;
- MonoDynamicGenericClass *gclass;
+ MonoGenericClass *gclass;
MonoReflectionTypeBuilder *tb = NULL;
MonoClass *klass = NULL;
MonoDomain *domain;
domain = mono_object_domain (type);
- g_assert (type->type.type->data.generic_class->is_dynamic);
- gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
+ gclass = type->type.type->data.generic_class;
+ g_assert (gclass->is_dynamic);
if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
tb = (MonoReflectionTypeBuilder *) type->generic_type;
icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
} else {
- klass = gclass->generic_class.generic_class.container_class;
+ klass = gclass->container_class;
mono_class_init (klass);
icount = klass->interface_count;
}
} else
it = &klass->interfaces [i]->byval_arg;
- it = mono_class_inflate_generic_type (
- it, gclass->generic_class.generic_class.context);
+ it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
iface = mono_type_get_object (domain, it);
mono_array_setref (res, i, iface);
if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
return NULL;
- method = type->type->data.generic_param->method;
+ method = type->type->data.generic_param->owner->owner.method;
g_assert (method);
klass = mono_class_from_mono_type (type->type);
return mono_method_get_object (mono_object_domain (type), method, klass);
MONO_ARCH_SAVE_REGS;
- if (!method->method->is_inflated) {
- if (mono_method_signature (method->method)->generic_param_count)
- return method;
+ if (method->method->generic_container)
+ return method;
+ if (!method->method->is_inflated)
return NULL;
- }
imethod = (MonoMethodInflated *) method->method;
- if (imethod->context->gmethod && imethod->context->gmethod->reflection_info)
- return imethod->context->gmethod->reflection_info;
+
+ if (imethod->reflection_info)
+ return imethod->reflection_info;
else
return mono_method_get_object (
mono_object_domain (method), imethod->declaring, NULL);
{
MONO_ARCH_SAVE_REGS;
- return !method->method->is_inflated &&
- (mono_method_signature (method->method)->generic_param_count != 0);
+ return method->method->generic_container != NULL;
}
static MonoArray*
domain = mono_object_domain (method);
if (method->method->is_inflated) {
- MonoMethodInflated *imethod = (MonoMethodInflated *) method->method;
- MonoGenericMethod *gmethod = imethod->context->gmethod;
+ MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
- if (gmethod) {
- count = gmethod->inst->type_argc;
+ if (inst) {
+ count = inst->type_argc;
res = mono_array_new (domain, mono_defaults.monotype_class, count);
for (i = 0; i < count; i++)
- mono_array_setref (res, i, mono_type_get_object (domain, gmethod->inst->type_argv [i]));
+ mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
return res;
}
return res;
}
+static void
+ensure_reflection_security (void)
+{
+ MonoMethod *m = mono_method_get_last_managed ();
+
+ while (m) {
+ /*
+ g_print ("method %s.%s.%s in image %s\n",
+ m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
+ */
+
+ /* We stop at the first method which is not in
+ System.Reflection or which is not in a platform
+ image. */
+ if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
+ !mono_security_core_clr_is_platform_image (m->klass->image)) {
+ /* If the method is transparent we throw an exception. */
+ if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
+ MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
+
+ mono_raise_exception (ex);
+ }
+ return;
+ }
+
+ mono_stack_walk_no_il (get_caller, &m);
+ }
+}
+
static MonoObject *
ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
{
* is stupid), mono_runtime_invoke_*() calls the provided method, allowing
* greater flexibility.
*/
- MonoMethod *m = mono_get_inflated_method (method->method);
+ MonoMethod *m = method->method;
int pcount;
void *obj = this;
MONO_ARCH_SAVE_REGS;
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
+ mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
+ ensure_reflection_security ();
+
if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
if (this) {
if (!mono_object_isinst (this, m->klass))
if (pcount != mono_method_signature (m)->param_count)
mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
- if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
+ if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
if (m->klass->image->assembly->ref_only)
} else if (!strcmp (m->name, "FieldSetter")) {
MonoClass *k = this->vtable->klass;
MonoString *name;
- int size, align;
+ guint32 size;
+ gint32 align;
char *str;
/* If this is a proxy, then it must be a CBO */
compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
handle_parent:
+ if (klass->exception_type != MONO_EXCEPTION_NONE)
+ mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
iter = NULL;
while ((field = mono_class_get_fields (klass, &iter))) {
match = 0;
+
+ if (field->type == NULL)
+ continue;
if (mono_field_is_deleted (field))
continue;
if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
len = 2;
res = mono_array_new (domain, mono_defaults.field_info_class, len);
handle_parent:
+ if (klass->exception_type != MONO_EXCEPTION_NONE)
+ mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
iter = NULL;
while ((field = mono_class_get_fields (klass, &iter))) {
match = 0;
if (bflags & BFLAGS_Public)
match++;
} else {
- if (bflags & BFLAGS_NonPublic)
- match++;
+ if (bflags & BFLAGS_NonPublic) {
+ /* Serialization currently depends on the old behavior.
+ * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
+ match++;
+ }
}
if (!match)
continue;
mono_class_setup_vtable (klass);
- nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
+ if (is_generic_parameter (type->type))
+ nslots = klass->parent->vtable_size;
+ else
+ nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
if (nslots >= sizeof (method_slots_default) * 8) {
method_slots = g_new0 (guint32, nslots / 32 + 1);
} else {
res = mono_array_new (domain, mono_defaults.method_info_class, len);
handle_parent:
mono_class_setup_vtable (klass);
+ if (klass->exception_type != MONO_EXCEPTION_NONE)
+ mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
iter = NULL;
while ((method = mono_class_get_methods (klass, &iter))) {
match = 0;
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");
res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
handle_parent:
mono_class_setup_vtable (klass);
+ if (klass->exception_type != MONO_EXCEPTION_NONE) {
+ if (method_slots != method_slots_default)
+ g_free (method_slots);
+ if (name != NULL)
+ g_free (propname);
+ mono_raise_exception (mono_class_get_exception_for_failure (klass));
+ }
+
iter = NULL;
while ((prop = mono_class_get_properties (klass, &iter))) {
match = 0;
domain = mono_object_domain (type);
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))
len = 2;
res = mono_array_new (domain, System_Reflection_EventInfo, len);
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))) {
match = 0;
ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
{
MonoDomain *domain;
- MonoClass *startklass, *klass;
+ MonoClass *klass;
MonoClass *nested;
GList *tmpn;
char *str;
domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref)
return NULL;
- klass = startklass = mono_class_from_mono_type (type->type);
+ klass = mono_class_from_mono_type (type->type);
str = mono_string_to_utf8 (name);
handle_parent:
+ 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.
+ * Note that this means that the return value is essentially a
+ * nested type of the generic type definition of @klass.
+ *
+ * A note in MSDN claims that a generic type definition can have
+ * nested types that aren't generic. In any case, the container of that
+ * nested type would be the generic type definition.
+ */
+ if (klass->generic_class)
+ klass = klass->generic_class->container_class;
+
for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
int match = 0;
nested = tmpn->data;
{
MonoDomain *domain;
GList *tmpn;
- MonoClass *startklass, *klass;
+ MonoClass *klass;
MonoArray *res;
MonoObject *member;
int i, len, match;
domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref)
return mono_array_new (domain, mono_defaults.monotype_class, 0);
- klass = startklass = mono_class_from_mono_type (type->type);
+ 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.
+ * Note that this means that the return value is essentially the set
+ * of nested types of the generic type definition of @klass.
+ *
+ * A note in MSDN claims that a generic type definition can have
+ * nested types that aren't generic. In any case, the container of that
+ * nested type would be the generic type definition.
+ */
+ if (klass->generic_class)
+ klass = klass->generic_class->container_class;
i = 0;
len = 1;
/*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
if (!mono_reflection_parse_type (str, &info)) {
g_free (str);
- g_list_free (info.modifiers);
- g_list_free (info.nested);
+ mono_reflection_free_type_info (&info);
if (throwOnError) /* uhm: this is a parse error, though... */
mono_raise_exception (mono_get_exception_type_load (name, NULL));
/*g_print ("failed parse\n");*/
else
type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
g_free (str);
- g_list_free (info.modifiers);
- g_list_free (info.nested);
+ mono_reflection_free_type_info (&info);
if (!type) {
+ MonoException *e = NULL;
+
if (throwOnError)
- mono_raise_exception (mono_get_exception_type_load (name, NULL));
- /* g_print ("failed find\n"); */
+ e = mono_get_exception_type_load (name, NULL);
+
+ mono_loader_clear_error ();
+
+ if (e != NULL)
+ mono_raise_exception (e);
+
return NULL;
}
if (throwOnError && klass->exception_type) {
/* report SecurityException (or others) that occured when loading the assembly */
MonoException *exc = mono_class_get_exception_for_failure (klass);
+ mono_loader_clear_error ();
mono_raise_exception (exc);
} else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
return NULL;
}
static MonoReflectionModule*
-ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
+ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
{
return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
}
return mono_method_get_object (mono_domain_get (), m, NULL);
}
+static MonoReflectionMethod*
+ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
+{
+ /* FIXME check that method belongs to klass or a parent */
+ MonoClass *klass;
+ if (type)
+ klass = mono_class_from_mono_type (type);
+ else
+ klass = method->klass;
+ return mono_method_get_object (mono_domain_get (), method, klass);
+}
+
static MonoReflectionMethod*
ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
{
if (!name)
return NULL;
- if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR))
+ if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
+ g_free (name);
return NULL;
+ }
res = mono_string_new (domain, name);
g_free (name);
MonoException *exc;
g_free (filename);
- exc = mono_get_exception_file_not_found (fname);
+ if (status == MONO_IMAGE_IMAGE_INVALID)
+ exc = mono_get_exception_bad_image_format2 (NULL, fname);
+ else
+ exc = mono_get_exception_file_not_found2 (NULL, fname);
mono_raise_exception (exc);
}
list = NULL;
exc = mono_get_exception_reflection_type_load (res, exl);
+ mono_loader_clear_error ();
mono_raise_exception (exc);
}
}
static gint32
-ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module)
+ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
{
- MonoImage *image = module->image;
-
- if (!image)
- mono_raise_exception (mono_get_exception_not_supported (""));
-
return (image->md_version_major << 16) | (image->md_version_minor);
}
return (*sig != 0x6);
}
+static void
+init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
+{
+ if (type_args)
+ context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
+ mono_array_addr (type_args, MonoType*, 0));
+ else
+ context->class_inst = NULL;
+ if (method_args)
+ context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
+ mono_array_addr (method_args, MonoType*, 0));
+ else
+ context->method_inst = NULL;
+}
+
static MonoType*
-ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
{
MonoClass *klass;
int table = mono_metadata_token_table (token);
int index = mono_metadata_token_index (token);
+ MonoGenericContext context;
*error = ResolveTokenError_Other;
return NULL;
}
- if (image->dynamic)
- return mono_lookup_dynamic_token (image, token);
+ if (image->dynamic) {
+ if (type_args || method_args)
+ mono_raise_exception (mono_get_exception_not_implemented (NULL));
+ return mono_lookup_dynamic_token (image, token, NULL);
+ }
if ((index <= 0) || (index > image->tables [table].rows)) {
*error = ResolveTokenError_OutOfRange;
return NULL;
}
- klass = mono_class_get (image, token);
+ init_generic_context_from_args (&context, type_args, method_args);
+ klass = mono_class_get_full (image, token, &context);
+
if (klass)
return &klass->byval_arg;
else
}
static MonoMethod*
-ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
{
int table = mono_metadata_token_table (token);
int index = mono_metadata_token_index (token);
+ MonoGenericContext context;
+ MonoMethod *method;
*error = ResolveTokenError_Other;
return NULL;
}
- if (image->dynamic)
+ 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 (image, token);
+ return mono_lookup_dynamic_token (image, token, NULL);
+ }
if ((index <= 0) || (index > image->tables [table].rows)) {
*error = ResolveTokenError_OutOfRange;
return NULL;
}
- return mono_get_method (image, token, NULL);
+ init_generic_context_from_args (&context, type_args, method_args);
+ method = mono_get_method_full (image, token, NULL, &context);
+
+ return method;
}
static MonoString*
}
if (image->dynamic)
- return mono_lookup_dynamic_token (image, token);
+ return mono_lookup_dynamic_token (image, token, NULL);
if ((index <= 0) || (index >= image->heap_us.size)) {
*error = ResolveTokenError_OutOfRange;
}
static MonoClassField*
-ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
{
MonoClass *klass;
int table = mono_metadata_token_table (token);
int index = mono_metadata_token_index (token);
+ MonoGenericContext context;
+ MonoClassField *field;
*error = ResolveTokenError_Other;
return NULL;
}
- if (image->dynamic)
+ 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 (image, token);
+ return mono_lookup_dynamic_token (image, token, NULL);
+ }
if ((index <= 0) || (index > image->tables [table].rows)) {
*error = ResolveTokenError_OutOfRange;
return NULL;
}
- return mono_field_from_token (image, token, &klass, NULL);
+ init_generic_context_from_args (&context, type_args, method_args);
+ field = mono_field_from_token (image, token, &klass, &context);
+
+ return field;
}
static MonoObject*
-ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
{
int table = mono_metadata_token_table (token);
case MONO_TABLE_TYPEDEF:
case MONO_TABLE_TYPEREF:
case MONO_TABLE_TYPESPEC: {
- MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
+ MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
if (t)
return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
else
}
case MONO_TABLE_METHOD:
case MONO_TABLE_METHODSPEC: {
- MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
+ 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);
else
return NULL;
}
case MONO_TABLE_FIELD: {
- MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
+ MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
if (f)
return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
else
}
case MONO_TABLE_MEMBERREF:
if (mono_metadata_memberref_is_method (image, token)) {
- MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
+ 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);
else
return NULL;
}
else {
- MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
+ MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
if (f)
return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
else
return NULL;
}
+static MonoArray*
+ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+{
+ int table = mono_metadata_token_table (token);
+ int idx = mono_metadata_token_index (token);
+ MonoTableInfo *tables = image->tables;
+ guint32 sig, len;
+ const char *ptr;
+ MonoArray *res;
+
+ *error = ResolveTokenError_OutOfRange;
+
+ /* FIXME: Support other tables ? */
+ if (table != MONO_TABLE_STANDALONESIG)
+ return NULL;
+
+ if (image->dynamic)
+ return NULL;
+
+ if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
+ return NULL;
+
+ sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
+
+ ptr = mono_metadata_blob_heap (image, sig);
+ len = mono_metadata_decode_blob_size (ptr, &ptr);
+
+ res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
+ memcpy (mono_array_addr (res, guint8, 0), ptr, len);
+ return res;
+}
+
static MonoReflectionType*
ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
{
}
static void
-ves_icall_System_Delegate_FreeTrampoline (MonoDelegate *this)
+ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
{
- /*
- Delegates have a finalizer only when needed, now.
- mono_delegate_free_ftnptr (this);*/
+ gpointer iter;
+ MonoMethod *invoke;
+
+ /* Find the Invoke method */
+ iter = NULL;
+ while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) {
+ if (!strcmp (invoke->name, "Invoke"))
+ break;
+ }
+ g_assert (invoke);
+
+ this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke));
}
/*
* There is no standard way to get at environ.
*/
#ifndef _MSC_VER
+#ifndef __MINGW32_VERSION
extern
-#endif
char **environ;
+#endif
+#endif
static MonoArray *
ves_icall_System_Environment_GetEnvironmentVariableNames (void)
return mcpath;
}
+static MonoString *
+get_bundled_machine_config (void)
+{
+ const gchar *machine_config;
+
+ MONO_ARCH_SAVE_REGS;
+
+ machine_config = mono_get_machine_config ();
+
+ if (!machine_config)
+ return NULL;
+
+ return mono_string_new (mono_domain_get (), machine_config);
+}
+
static MonoString *
ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
{
ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
{
#if defined (PLATFORM_WIN32)
- static void (*output_debug) (gunichar2 *);
- static gboolean tried_loading = FALSE;
-
- MONO_ARCH_SAVE_REGS;
-
- if (!tried_loading && output_debug == NULL) {
- GModule *k32;
-
- tried_loading = TRUE;
- k32 = g_module_open ("kernel32", G_MODULE_BIND_LAZY);
- if (!k32) {
- gchar *error = g_strdup (g_module_error ());
- g_warning ("Failed to load kernel32.dll: %s\n", error);
- g_free (error);
- return;
- }
-
- g_module_symbol (k32, "OutputDebugStringW", (gpointer *) &output_debug);
- if (!output_debug) {
- gchar *error = g_strdup (g_module_error ());
- g_warning ("Failed to load OutputDebugStringW: %s\n", error);
- g_free (error);
- return;
- }
- }
-
- if (output_debug == NULL)
- return;
-
- output_debug (mono_string_chars (message));
+ OutputDebugString (mono_string_chars (message));
#else
g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
#endif
return mono_method_get_object (mono_domain_get (), result, NULL);
}
+static MonoString*
+ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
+{
+ MonoMethod *method = m->method;
+
+ MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
+ return m->name;
+}
+
static void
mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
{
if (start) {
iter->args = start;
} else {
- int i, align, arg_size;
+ guint32 i, arg_size;
+ gint32 align;
iter->args = argsp + sizeof (gpointer);
#ifndef MONO_ARCH_REGPARMS
for (i = 0; i < iter->sig->sentinelpos; ++i) {
static MonoTypedRef
mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
{
- gint i, align, arg_size;
+ guint32 i, arg_size;
+ gint32 align;
MonoTypedRef res;
MONO_ARCH_SAVE_REGS;
static MonoTypedRef
mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
{
- gint i, align, arg_size;
+ guint32 i, arg_size;
+ gint32 align;
MonoTypedRef res;
MONO_ARCH_SAVE_REGS;
return method->method->token;
}
+/*
+ * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
+ * and avoid useless allocations.
+ */
+static MonoArray*
+type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
+{
+ MonoArray *res;
+ int i, count = 0;
+ for (i = 0; i < type->num_mods; ++i) {
+ if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
+ count++;
+ }
+ if (!count)
+ return NULL;
+ res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
+ count = 0;
+ for (i = 0; i < type->num_mods; ++i) {
+ if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
+ MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
+ mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
+ count++;
+ }
+ }
+ return res;
+}
+
+static MonoArray*
+param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
+{
+ MonoType *type = param->ClassImpl->type;
+ MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
+ MonoImage *image = method->method->klass->image;
+ int pos = param->PositionImpl;
+ MonoMethodSignature *sig = mono_method_signature (method->method);
+ if (pos == -1)
+ type = sig->ret;
+ else
+ type = sig->params [pos];
+
+ return type_array_from_modifiers (image, type, optional);
+}
+
+static MonoType*
+get_property_type (MonoProperty *prop)
+{
+ MonoMethodSignature *sig;
+ if (prop->get) {
+ sig = mono_method_signature (prop->get);
+ return sig->ret;
+ } else if (prop->set) {
+ sig = mono_method_signature (prop->set);
+ return sig->params [sig->param_count - 1];
+ }
+ return NULL;
+}
+
+static MonoArray*
+property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
+{
+ MonoType *type = get_property_type (property->property);
+ MonoImage *image = property->klass->image;
+
+ if (!type)
+ return NULL;
+ return type_array_from_modifiers (image, type, optional);
+}
+
static MonoBoolean
custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
{
static MonoArray*
custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
{
- return mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
+ MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
+
+ if (mono_loader_get_last_error ()) {
+ mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+ g_assert_not_reached ();
+ } else {
+ return res;
+ }
}
static MonoBoolean
klass = mono_defaults.int32_class;
else if (!strcmp (typename, "uint32"))
klass = mono_defaults.uint32_class;
+ else if (!strcmp (typename, "int8"))
+ klass = mono_defaults.sbyte_class;
+ else if (!strcmp (typename, "uint8"))
+ klass = mono_defaults.byte_class;
+ else if (!strcmp (typename, "int16"))
+ klass = mono_defaults.int16_class;
+ else if (!strcmp (typename, "uint16"))
+ klass = mono_defaults.uint16_class;
else if (!strcmp (typename, "long"))
klass = mono_defaults.int64_class;
else if (!strcmp (typename, "ulong"))