#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))
memcpy (value, ea, esize);
}
+static void
+ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
+{
+ MonoClass *ac;
+ MonoArray *ao;
+ gint32 esize;
+ gpointer *ea;
+
+ MONO_ARCH_SAVE_REGS;
+
+ ao = (MonoArray *)this;
+ ac = (MonoClass *)ao->obj.vtable->klass;
+
+ 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)
{
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)
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 ());
{
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);
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
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->context.class_inst;
- res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
+ 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;
}
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;
{
MONO_ARCH_SAVE_REGS;
- return method->method->generic_container &&
- (mono_method_signature (method->method)->generic_param_count != 0);
+ return method->method->generic_container != NULL;
}
static MonoArray*
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))
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;
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;
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
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.
/*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;
}
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);
}
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);
static void
init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
{
- MonoGenericInst *class_inst, *method_inst;
-
- class_inst = g_new0 (MonoGenericInst, 1);
- method_inst = g_new0 (MonoGenericInst, 1);
- context->class_inst = class_inst;
- context->method_inst = method_inst;
- if (type_args) {
- class_inst->type_argc = mono_array_length (type_args);
- class_inst->type_argv = g_malloc (sizeof (MonoType*) * class_inst->type_argc);
- memcpy (class_inst->type_argv, mono_array_addr (type_args, MonoType*, 0), class_inst->type_argc * sizeof (MonoType*));
- }
- if (method_args) {
- method_inst->type_argc = mono_array_length (method_args);
- method_inst->type_argv = g_malloc (sizeof (MonoType*) * method_inst->type_argc);
- memcpy (method_inst->type_argv, mono_array_addr (method_args, MonoType*, 0), method_inst->type_argc * sizeof (MonoType*));
- }
-}
-
-static void
-free_generic_context (MonoGenericContext *context)
-{
- g_free (context->class_inst->type_argv);
- g_free (context->class_inst);
- g_free (context->method_inst->type_argv);
- g_free (context->method_inst);
+ 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*
if (image->dynamic) {
if (type_args || method_args)
mono_raise_exception (mono_get_exception_not_implemented (NULL));
- return mono_lookup_dynamic_token (image, token);
+ return mono_lookup_dynamic_token (image, token, NULL);
}
if ((index <= 0) || (index > image->tables [table].rows)) {
init_generic_context_from_args (&context, type_args, method_args);
klass = mono_class_get_full (image, token, &context);
- free_generic_context (&context);
if (klass)
return &klass->byval_arg;
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)) {
init_generic_context_from_args (&context, type_args, method_args);
method = mono_get_method_full (image, token, NULL, &context);
- free_generic_context (&context);
return method;
}
}
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;
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)) {
init_generic_context_from_args (&context, type_args, method_args);
field = mono_field_from_token (image, token, &klass, &context);
- free_generic_context (&context);
return field;
}
}
static MonoString *
-ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
+get_bundled_machine_config (void)
{
const gchar *machine_config;
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)
{
}
/*
- * We eturn NULL for no modifiers so the corlib code can return Type.EmptyTypes
+ * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
* and avoid useless allocations.
*/
static MonoArray*