* Paolo Molaro (lupus@ximian.com)
* Patrik Torstensson (patrik.torstensson@labs2.com)
*
- * (C) 2001 Ximian, Inc.
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
*/
#include <config.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
#include <stdlib.h>
#endif
#include <mono/utils/monobitset.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-string.h>
+#include <mono/utils/mono-error-internals.h>
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
#include <windows.h>
#include <shlobj.h>
#endif
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);
}
-#ifdef _EGLIB_MAJOR
-/* Need to lock here because EGLIB has locking defined as no-ops, we can not depend on mono_strtod do the right locking */
-/* Ideally this will be fixed in eglib */
-static CRITICAL_SECTION strtod_mutex;
-#endif
-
/*
* We expect a pointer to a char, not a string
*/
#else
if (*ptr){
#ifdef _EGLIB_MAJOR
- /* Need to lock here because EGLIB has locking defined as no-ops, and that breaks mono_strtod */
- EnterCriticalSection (&strtod_mutex);
+ /* Need to lock here because EGLIB (#464316) has locking defined as no-ops, and that breaks mono_strtod */
+ EnterCriticalSection (&mono_strtod_mutex);
*result = mono_strtod (ptr, &endptr);
- LeaveCriticalSection (&strtod_mutex);
+ LeaveCriticalSection (&mono_strtod_mutex);
#else
*result = mono_strtod (ptr, &endptr);
#endif
for (i = 0; i < ac->rank; i++)
if ((ind [i] < ao->bounds [i].lower_bound) ||
- (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
+ (ind [i] >= (mono_array_lower_bound_t)ao->bounds [i].length + ao->bounds [i].lower_bound))
mono_raise_exception (mono_get_exception_index_out_of_range ());
pos = ind [0] - ao->bounds [0].lower_bound;
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;
+ et = mono_class_enum_basetype (ec->byval_arg.data.klass)->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;
+ vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
#define ASSIGN_UNSIGNED(etype) G_STMT_START{\
switch (vt) { \
for (i = 0; i < ac->rank; i++)
if ((ind [i] < this->bounds [i].lower_bound) ||
- (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
+ (ind [i] >= (mono_array_lower_bound_t)this->bounds [i].length + this->bounds [i].lower_bound))
mono_raise_exception (mono_get_exception_index_out_of_range ());
pos = ind [0] - this->bounds [0].lower_bound;
if (source->bounds || dest->bounds)
return FALSE;
+ /* there's no integer overflow since mono_array_length returns an unsigned integer */
if ((dest_idx + length > mono_array_length (dest)) ||
(source_idx + length > mono_array_length (source)))
return FALSE;
static void
ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
{
- MonoClass *ac;
+ MonoClass *ac, *ec;
MonoArray *ao;
gint32 esize;
gpointer *ea;
ao = (MonoArray *)this;
ac = (MonoClass *)ao->obj.vtable->klass;
+ ec = ac->element_class;
esize = mono_array_element_size (ac);
ea = (gpointer*)((char*)ao->vector + (pos * esize));
- memcpy (ea, value, esize);
+ if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
+ g_assert (esize == sizeof (gpointer));
+ mono_gc_wbarrier_generic_store (ea, *(gpointer*)value);
+ } else {
+ g_assert (ec->inited);
+ g_assert (esize == mono_class_value_size (ec, NULL));
+ if (ec->has_references)
+ mono_gc_wbarrier_value_copy (ea, value, 1, ec);
+ else
+ memcpy (ea, value, esize);
+ }
}
static void
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
{
MonoClass *klass;
-
- MONO_ARCH_SAVE_REGS;
+ MonoVTable *vtable;
MONO_CHECK_ARG_NULL (handle);
klass = mono_class_from_mono_type (handle);
MONO_CHECK_ARG (handle, klass);
+ vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE);
+
/* This will call the type constructor */
- mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
+ mono_runtime_class_init (vtable);
}
static void
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));
+ /*It's fine to raise the exception here*/
+ mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass, TRUE));
}
}
if (values) {
int i;
- *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
+ mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
for (i = 0; i < count; ++i)
mono_array_setref (*fields, i, values [i]);
} else {
klass = mono_object_class (this);
- if (klass->enumtype && klass->enum_basetype && klass->enum_basetype->type == MONO_TYPE_I4)
+ if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
return (*(gint32*)((guint8*)this + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
/*
if (values) {
int i;
- *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
+ mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
for (i = 0; i < count; ++i)
mono_array_setref (*fields, i, values [i]);
return FALSE;
return FALSE;
}
+static gboolean
+get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+{
+ MonoMethod **dest = data;
+
+ /* skip unmanaged frames */
+ if (!managed)
+ return FALSE;
+
+ if (m->wrapper_type != MONO_WRAPPER_NONE)
+ return FALSE;
+
+ if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
+ return FALSE;
+
+ if (m == *dest) {
+ *dest = NULL;
+ return FALSE;
+ }
+ if (!(*dest)) {
+ *dest = m;
+ return TRUE;
+ }
+ return FALSE;
+}
+
static MonoReflectionType *
type_from_name (const char *str, MonoBoolean ignoreCase)
{
MonoMethod *m = mono_method_get_last_managed ();
MonoMethod *dest = m;
- mono_stack_walk_no_il (get_caller, &dest);
+ mono_stack_walk_no_il (get_caller_no_reflection, &dest);
if (!dest)
dest = m;
if (c && type->type && c->type)
return mono_metadata_type_equal (type->type, c->type);
else
- return FALSE;
+ return (type == c) ? TRUE : FALSE;
}
/* System.TypeCode */
return TYPECODE_DOUBLE;
case MONO_TYPE_VALUETYPE:
if (type->type->data.klass->enumtype) {
- t = type->type->data.klass->enum_basetype->type;
+ t = mono_class_enum_basetype (type->type->data.klass)->type;
goto handle_enum;
} else {
MonoClass *k = type->type->data.klass;
}
static MonoReflectionField*
-ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
+ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
{
+ gboolean found = FALSE;
+ MonoClass *klass;
+ MonoClass *k;
+
g_assert (handle);
- if (!klass)
+ if (!type) {
klass = handle->parent;
+ } else {
+ klass = mono_class_from_mono_type (type);
- /* 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)
-{
- MONO_ARCH_SAVE_REGS;
+ /* Check that the field belongs to the class */
+ for (k = klass; k; k = k->parent) {
+ if (k == handle->parent) {
+ found = TRUE;
+ break;
+ }
+ }
- g_assert (handle);
+ if (!found)
+ /* The managed code will throw the exception */
+ return NULL;
+ }
- return mono_field_get_object (mono_domain_get (), handle->parent, handle);
+ return mono_field_get_object (mono_domain_get (), klass, handle);
}
static MonoArray*
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);
+
+ 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));
info->attrs = method->flags;
info->implattrs = method->iflags;
if (sig->call_convention == MONO_CALL_DEFAULT)
}
static MonoArray*
-ves_icall_get_parameter_info (MonoMethod *method)
+ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
{
MonoDomain *domain = mono_domain_get ();
- return mono_param_get_objects (domain, method);
+ return mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL);
}
static MonoReflectionMarshal*
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)
vtable = NULL;
if (is_static) {
- vtable = mono_class_vtable (domain, cf->parent);
+ vtable = mono_class_vtable_full (domain, cf->parent, TRUE);
if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
mono_runtime_class_init (vtable);
}
mono_raise_exception (mono_get_exception_invalid_operation (
"It is illegal to set 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);
+
v = (gchar *) value;
if (!cf->type->byref) {
switch (cf->type->type) {
}
if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
- MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
+ MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, TRUE);
if (!vtable->initialized)
mono_runtime_class_init (vtable);
mono_field_static_set_value (vtable, cf, v);
}
static void
-ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
+ves_icall_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
{
MonoDomain *domain = mono_object_domain (event);
MONO_ARCH_SAVE_REGS;
- info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
- info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
+ MONO_STRUCT_SETREF (info, reflected_type, mono_type_get_object (domain, &event->klass->byval_arg));
+ MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &event->event->parent->byval_arg));
- info->name = mono_string_new (domain, event->event->name);
+ MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
info->attrs = event->event->attrs;
- info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
- info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
- info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
+ MONO_STRUCT_SETREF (info, add_method, event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL);
+ 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);
if (event->event->other) {
int i, n = 0;
while (event->event->other [n])
n++;
- info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
+ MONO_STRUCT_SETREF (info, other_methods, mono_array_new (domain, mono_defaults.method_info_class, n));
for (i = 0; i < n; i++)
mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
mono_bitset_free (slots);
if (!ifaces)
- return mono_array_new (domain, mono_defaults.monotype_class, 0);
+ return mono_array_new_cached (domain, mono_defaults.monotype_class, 0);
- intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
+ 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;
len = mono_class_num_methods (iclass);
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);
- iter = NULL;
+ mono_gc_wbarrier_generic_store (targets, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len));
+ mono_gc_wbarrier_generic_store (methods, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len));
iter = NULL;
while ((method = mono_class_get_methods (iclass, &iter))) {
member = mono_method_get_object (domain, method, iclass);
static MonoReflectionType*
ves_icall_MonoType_GetElementType (MonoReflectionType *type)
{
- MonoClass *class = mono_class_from_mono_type (type->type);
+ MonoClass *class;
MONO_ARCH_SAVE_REGS;
+ if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY)
+ return mono_type_get_object (mono_object_domain (type), &type->type->data.klass->byval_arg);
+
+ class = mono_class_from_mono_type (type->type);
+
// GetElementType should only return a type for:
// Array Pointer PassedByRef
if (type->type->byref)
if (type->type->byref)
return NULL;
if (type->type->type == MONO_TYPE_VAR)
- class = type->type->data.generic_param->owner->owner.klass;
+ class = mono_type_get_generic_param_owner (type->type)->owner.klass;
else if (type->type->type == MONO_TYPE_MVAR)
- class = type->type->data.generic_param->owner->owner.method->klass;
+ class = mono_type_get_generic_param_owner (type->type)->owner.method->klass;
else
class = mono_class_from_mono_type (type->type)->nested_in;
MONO_ARCH_SAVE_REGS;
- if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
- return mono_type_get_object (domain, class->enum_basetype);
+ 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
static gint32
ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
{
- MonoClass *class = mono_class_from_mono_type (type->type);
+ MonoClass *class;
- MONO_ARCH_SAVE_REGS;
+ if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY)
+ 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;
}
{
MonoArray *res;
MonoClass *klass, *pklass;
+ MonoDomain *domain = mono_object_domain (type);
+ MonoVTable *array_vtable = mono_class_vtable_full (domain, mono_array_class_get_cached (mono_defaults.systemtype_class, 1), TRUE);
int i;
MONO_ARCH_SAVE_REGS;
if (klass->generic_container) {
MonoGenericContainer *container = klass->generic_container;
- res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
+ res = mono_array_new_specific (array_vtable, 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));
+ pklass = mono_class_from_generic_parameter (mono_generic_container_get_param (container, i), klass->image, FALSE);
+ mono_array_setref (res, i, mono_type_get_object (domain, &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.systemtype_class, inst->type_argc);
+ res = mono_array_new_specific (array_vtable, 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]));
+ mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
} else {
- res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
+ res = mono_array_new_specific (array_vtable, 0);
}
return res;
}
MonoClass *klass;
MONO_ARCH_SAVE_REGS;
+ if (!IS_MONOTYPE (type))
+ return FALSE;
+
if (type->type->byref)
return FALSE;
MonoClass *klass;
MONO_ARCH_SAVE_REGS;
+ if (!IS_MONOTYPE (type))
+ return FALSE;
+
if (type->type->byref)
return FALSE;
{
MONO_ARCH_SAVE_REGS;
+ if (!IS_MONOTYPE (type))
+ return -1;
+
if (is_generic_parameter (type->type))
- return type->type->data.generic_param->num;
+ return mono_type_get_generic_param_num (type->type);
return -1;
}
ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
{
MONO_ARCH_SAVE_REGS;
+
+ g_assert (IS_MONOTYPE (type));
g_assert (is_generic_parameter (type->type));
- return type->type->data.generic_param->flags;
+ return mono_generic_param_info (type->type->data.generic_param)->flags;
}
static MonoArray *
ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
{
- MonoGenericParam *param;
+ MonoGenericParamInfo *param_info;
MonoDomain *domain;
MonoClass **ptr;
MonoArray *res;
MONO_ARCH_SAVE_REGS;
+ g_assert (IS_MONOTYPE (type));
+
domain = mono_object_domain (type);
- param = type->type->data.generic_param;
- for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
+ param_info = mono_generic_param_info (type->type->data.generic_param);
+ for (count = 0, ptr = param_info->constraints; ptr && *ptr; ptr++, count++)
;
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, ¶m->constraints [i]->byval_arg));
+ mono_array_setref (res, i, mono_type_get_object (domain, ¶m_info->constraints [i]->byval_arg));
return res;
enumtype->type = t->type;
}
-static MonoReflectionType*
-ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
-{
- MonoDynamicGenericClass *gclass;
- MonoReflectionType *parent = NULL, *res;
- MonoDomain *domain;
- MonoType *inflated;
- MonoClass *klass;
-
-
- MONO_ARCH_SAVE_REGS;
-
- g_assert (type->type.type->data.generic_class->is_dynamic);
- gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
-
- domain = mono_object_domain (type);
- klass = mono_class_from_mono_type (type->generic_type->type.type);
-
- if (!klass->generic_class && !klass->generic_container)
- return NULL;
-
- parent = type->generic_type->parent;
-
- if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
- return NULL;
-
- inflated = mono_class_inflate_generic_type (
- parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
-
- res = mono_type_get_object (domain, inflated);
- mono_metadata_free_type (inflated);
- return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
-{
- static MonoClass *System_Reflection_MonoGenericClass;
- MonoGenericClass *gclass;
- MonoReflectionTypeBuilder *tb = NULL;
- MonoClass *klass = NULL;
- MonoDomain *domain;
- MonoArray *res;
- int icount, i;
-
- MONO_ARCH_SAVE_REGS;
-
- if (!System_Reflection_MonoGenericClass) {
- System_Reflection_MonoGenericClass = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
- g_assert (System_Reflection_MonoGenericClass);
- }
-
- domain = mono_object_domain (type);
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
-
- tb = type->generic_type;
- icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
-
- res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
-
- for (i = 0; i < icount; i++) {
- MonoReflectionType *iface;
- MonoType *it;
-
- if (tb) {
- iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
- it = iface->type;
- } else
- it = &klass->interfaces [i]->byval_arg;
-
- 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);
- mono_metadata_free_type (it);
- }
-
- return res;
-}
-
-static MonoReflectionMethod*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
- MonoReflectionMethod* generic)
-{
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
-
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- domain = mono_object_domain (type);
-
- for (i = 0; i < dgclass->count_methods; i++)
- if (generic->method->token == dgclass->methods [i]->token)
- return mono_method_get_object (domain, dgclass->methods [i], NULL);
-
- return NULL;
-}
-
-static MonoReflectionMethod*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
- MonoReflectionMethod* generic)
-{
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
-
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- domain = mono_object_domain (type);
-
- for (i = 0; i < dgclass->count_ctors; i++)
- if (generic->method->token == dgclass->ctors [i]->token)
- return mono_method_get_object (domain, dgclass->ctors [i], NULL);
-
- return NULL;
-}
-
-
-static MonoReflectionField*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
- MonoString* generic_name)
-{
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- MonoClass *refclass;
- char *utf8_name = mono_string_to_utf8 (generic_name);
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
-
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- refclass = mono_class_from_mono_type (type->type.type);
-
- domain = mono_object_domain (type);
-
- for (i = 0; i < dgclass->count_fields; i++)
- if (strcmp (utf8_name, mono_field_get_name (&dgclass->fields [i])) == 0) {
- g_free (utf8_name);
- return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
- }
-
- g_free (utf8_name);
-
- return NULL;
-}
-
-
static MonoReflectionMethod*
ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
MonoReflectionMethod* generic)
return NULL;
}
-static MonoArray*
-ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
- MonoReflectionType *reflected_type)
-{
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- MonoClass *refclass;
- MonoArray *res;
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- refclass = mono_class_from_mono_type (reflected_type->type);
- domain = mono_object_domain (type);
- res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
-
- for (i = 0; i < dgclass->count_methods; i++)
- mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
-
- return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
- MonoReflectionType *reflected_type)
-{
- static MonoClass *System_Reflection_ConstructorInfo;
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- MonoClass *refclass;
- MonoArray *res;
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- if (!System_Reflection_ConstructorInfo)
- System_Reflection_ConstructorInfo = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- refclass = mono_class_from_mono_type (reflected_type->type);
-
- domain = mono_object_domain (type);
- res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
-
- for (i = 0; i < dgclass->count_ctors; i++)
- mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
-
- return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
- MonoReflectionType *reflected_type)
-{
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- MonoClass *refclass;
- MonoArray *res;
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- refclass = mono_class_from_mono_type (reflected_type->type);
-
- domain = mono_object_domain (type);
- res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
-
- for (i = 0; i < dgclass->count_fields; i++)
- mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
-
- return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
- MonoReflectionType *reflected_type)
-{
- static MonoClass *System_Reflection_PropertyInfo;
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- MonoClass *refclass;
- MonoArray *res;
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- if (!System_Reflection_PropertyInfo)
- System_Reflection_PropertyInfo = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "PropertyInfo");
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- refclass = mono_class_from_mono_type (reflected_type->type);
-
- domain = mono_object_domain (type);
- res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
-
- for (i = 0; i < dgclass->count_properties; i++)
- mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
-
- return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
- MonoReflectionType *reflected_type)
-{
- static MonoClass *System_Reflection_EventInfo;
- MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoDomain *domain;
- MonoClass *refclass;
- MonoArray *res;
- int i;
-
- MONO_ARCH_SAVE_REGS;
-
- if (!System_Reflection_EventInfo)
- System_Reflection_EventInfo = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "EventInfo");
-
- gclass = type->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
-
- refclass = mono_class_from_mono_type (reflected_type->type);
-
- domain = mono_object_domain (type);
- res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
-
- for (i = 0; i < dgclass->count_events; i++)
- mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
-
- return res;
-}
-
-static MonoReflectionType*
-ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass *type,
- MonoReflectionType *target)
-{
- MonoType *res_type;
- MonoClass *gklass;
- MonoReflectionType *res;
-
- MONO_ARCH_SAVE_REGS;
-
- gklass = mono_class_from_mono_type (type->type.type);
- res_type = mono_class_inflate_generic_type (target->type, mono_class_get_context (gklass));
- res = mono_type_get_object (mono_object_domain (type), res_type);
- mono_metadata_free_type (res_type);
- return res;
-}
static MonoReflectionMethod *
-ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
+ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *ref_type)
{
MonoMethod *method;
- MonoClass *klass;
+ MonoType *type = ref_type->type;
MONO_ARCH_SAVE_REGS;
- if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
+ if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR))
+ mono_raise_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
+ if (type->type == MONO_TYPE_VAR)
return NULL;
- method = type->type->data.generic_param->owner->owner.method;
+ method = mono_type_get_generic_param_owner (type)->owner.method;
g_assert (method);
- klass = mono_class_from_mono_type (type->type);
- return mono_method_get_object (mono_object_domain (type), method, klass);
+ return mono_method_get_object (mono_object_domain (ref_type), method, method->klass);
}
static MonoReflectionDllImportAttribute*
const char *scope = NULL;
guint32 flags;
- if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+ if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
return NULL;
if (!DllImportAttributeClass) {
import = method_aux->dllentry;
scope = method_aux->dll;
}
+
+ if (!import || !scope) {
+ mono_raise_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
+ return NULL;
+ }
}
else {
if (piinfo->implmap_idx) {
for (i = 0; i < count; i++) {
MonoGenericContainer *container = mono_method_get_generic_container (method->method);
- MonoGenericParam *param = &container->type_params [i];
- MonoClass *pklass = mono_class_from_generic_parameter (
- param, method->method->klass->image, TRUE);
- mono_array_setref (res, i,
- mono_type_get_object (domain, &pklass->byval_arg));
- }
-
- 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);
+ MonoGenericParam *param = mono_generic_container_get_param (container, i);
+ MonoClass *pklass = mono_class_from_generic_parameter (
+ param, method->method->klass->image, TRUE);
+ mono_array_setref (res, i,
+ mono_type_get_object (domain, &pklass->byval_arg));
}
+
+ return res;
}
static MonoObject *
*exc = NULL;
- 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 (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ mono_security_core_clr_ensure_reflection_access_method (m);
if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
if (this) {
if (!mono_object_isinst (this, m->klass)) {
- *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type.");
+ mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type."));
return NULL;
}
m = mono_object_get_virtual_method (this, m);
if (m->klass->valuetype)
obj = mono_object_unbox (this);
} else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
- *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target.");
+ mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
return NULL;
}
}
pcount = params? mono_array_length (params): 0;
if (pcount != mono_method_signature (m)->param_count) {
- *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException");
+ mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
return NULL;
}
if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) {
- *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
+ mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class."));
return NULL;
}
if (m->klass->image->assembly->ref_only) {
- *exc = mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
+ mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
return NULL;
}
result = *((gpointer *)((char *)this + field->offset));
out_args = mono_array_new (domain, mono_defaults.object_class, 1);
- *outArgs = out_args;
+ mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
mono_array_setref (out_args, 0, result);
g_free (str);
return NULL;
if (field_klass->valuetype) {
size = mono_type_size (field->type, &align);
- memcpy ((char *)this + field->offset,
- ((char *)val) + sizeof (MonoObject), size);
- } else
- *(MonoObject**)((char *)this + field->offset) = val;
+ g_assert (size == mono_class_value_size (field_klass, NULL));
+ mono_gc_wbarrier_value_copy ((char *)this + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
+ } else {
+ mono_gc_wbarrier_set_field (this, (char*)this + field->offset, val);
+ }
out_args = mono_array_new (domain, mono_defaults.object_class, 0);
- *outArgs = out_args;
+ mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
g_free (str);
return NULL;
}
}
- *outArgs = out_args;
+ mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
return result;
}
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."));
res = mono_object_new (domain, enumc);
- val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
- write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
+ 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);
return res;
}
g_assert (this->vtable->klass->enumtype);
- enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
+ enumc = mono_class_from_mono_type (mono_class_enum_basetype (this->vtable->klass));
res = mono_object_new (mono_object_domain (this), enumc);
dst = (char *)res + sizeof (MonoObject);
src = (char *)this + sizeof (MonoObject);
{
MONO_ARCH_SAVE_REGS;
- return mono_type_get_object (mono_object_domain (type), mono_class_from_mono_type (type->type)->enum_basetype);
+ return mono_type_get_object (mono_object_domain (type), mono_class_enum_basetype (mono_class_from_mono_type (type->type)));
+}
+
+static int
+ves_icall_System_Enum_compare_value_to (MonoObject *this, MonoObject *other)
+{
+ gpointer tdata = (char *)this + sizeof (MonoObject);
+ gpointer odata = (char *)other + sizeof (MonoObject);
+ MonoType *basetype = mono_class_enum_basetype (this->vtable->klass);
+ g_assert (basetype);
+
+#define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
+ ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
+ ENUM_TYPE other = *((ENUM_TYPE*)odata); \
+ if (me == other) \
+ return 0; \
+ return me > other ? 1 : -1; \
+ } while (0)
+
+#define COMPARE_ENUM_VALUES_RANGE(ENUM_TYPE) do { \
+ ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
+ ENUM_TYPE other = *((ENUM_TYPE*)odata); \
+ if (me == other) \
+ return 0; \
+ return me - other; \
+ } while (0)
+
+ switch (basetype->type) {
+ case MONO_TYPE_U1:
+ COMPARE_ENUM_VALUES (guint8);
+ case MONO_TYPE_I1:
+ COMPARE_ENUM_VALUES (gint8);
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_U2:
+ COMPARE_ENUM_VALUES_RANGE (guint16);
+ case MONO_TYPE_I2:
+ COMPARE_ENUM_VALUES (gint16);
+ case MONO_TYPE_U4:
+ COMPARE_ENUM_VALUES (guint32);
+ case MONO_TYPE_I4:
+ COMPARE_ENUM_VALUES (gint32);
+ case MONO_TYPE_U8:
+ COMPARE_ENUM_VALUES (guint64);
+ case MONO_TYPE_I8:
+ COMPARE_ENUM_VALUES (gint64);
+ default:
+ g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
+ }
+#undef COMPARE_ENUM_VALUES_RANGE
+#undef COMPARE_ENUM_VALUES
+ return 0;
}
static int
ves_icall_System_Enum_get_hashcode (MonoObject *this)
{
gpointer data = (char *)this + sizeof (MonoObject);
- MonoType *basetype = this->vtable->klass->enum_basetype;
+ MonoType *basetype = mono_class_enum_basetype (this->vtable->klass);
g_assert (basetype);
switch (basetype->type) {
MONO_ARCH_SAVE_REGS;
- info->utype = mono_type_get_object (domain, enumc->enum_basetype);
+ 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;
- info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
- info->values = mono_array_new (domain, enumc, nvalues);
-
+ MONO_STRUCT_SETREF (info, names, mono_array_new (domain, mono_defaults.string_class, nvalues));
+ MONO_STRUCT_SETREF (info, values, mono_array_new (domain, enumc, nvalues));
+
crow = -1;
iter = NULL;
while ((field = mono_class_get_fields (enumc, &iter))) {
p = mono_class_get_field_default_value (field, &def_type);
len = mono_metadata_decode_blob_size (p, &p);
- switch (enumc->enum_basetype->type) {
+ switch (mono_class_enum_basetype (enumc)->type) {
case MONO_TYPE_U1:
case MONO_TYPE_I1:
mono_array_set (info->values, gchar, j, *p);
mono_array_set (info->values, gint64, j, read64 (p));
break;
default:
- g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
+ g_error ("Implement type 0x%02x in get_enum_info", mono_class_enum_basetype (enumc)->type);
}
++j;
}
if (type->type->byref)
return NULL;
- compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
+ compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
handle_parent:
if (klass->exception_type != MONO_EXCEPTION_NONE)
MonoClass *startklass, *klass, *refklass;
MonoArray *res;
MonoObject *member;
- int i, len, match;
+ int i, match;
gpointer iter;
MonoClassField *field;
+ MonoPtrArray tmp_array;
MONO_ARCH_SAVE_REGS;
klass = startklass = mono_class_from_mono_type (type->type);
refklass = mono_class_from_mono_type (reftype->type);
- i = 0;
- len = 2;
- res = mono_array_new (domain, mono_defaults.field_info_class, len);
+ mono_ptr_array_init (tmp_array, 2);
+
handle_parent:
if (klass->exception_type != MONO_EXCEPTION_NONE)
mono_raise_exception (mono_class_get_exception_for_failure (klass));
if (!match)
continue;
member = (MonoObject*)mono_field_get_object (domain, refklass, field);
- if (i >= len) {
- MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
- mono_array_memcpy_refs (new_res, 0, res, 0, len);
- len *= 2;
- res = new_res;
- }
- mono_array_setref (res, i, member);
- ++i;
+ mono_ptr_array_append (tmp_array, member);
}
if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
goto handle_parent;
- if (i != len) {
- MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
- mono_array_memcpy_refs (new_res, 0, res, 0, i);
- res = new_res;
- /*
- * Better solution for the new GC.
- * res->max_length = i;
- */
- }
+
+ res = mono_array_new_cached (domain, mono_defaults.field_info_class, mono_ptr_array_size (tmp_array));
+
+ for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+ mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+ mono_ptr_array_destroy (tmp_array);
+
return res;
}
gpointer iter;
MonoObject *member;
int i, len, match, nslots;
+ /*FIXME, use MonoBitSet*/
guint32 method_slots_default [8];
- guint32 *method_slots;
+ guint32 *method_slots = NULL;
gchar *mname = NULL;
int (*compare_func) (const char *s1, const char *s2) = NULL;
MonoVTable *array_vtable;
-
+ MonoException *ex;
+ MonoPtrArray tmp_array;
+
MONO_ARCH_SAVE_REGS;
+ mono_ptr_array_init (tmp_array, 4);
+
if (!MethodInfo_array) {
MonoClass *klass = mono_array_class_get (mono_defaults.method_info_class, 1);
mono_memory_barrier ();
}
domain = ((MonoObject *)type)->vtable->domain;
- array_vtable = mono_class_vtable (domain, MethodInfo_array);
+ array_vtable = mono_class_vtable_full (domain, MethodInfo_array, TRUE);
if (type->type->byref)
return mono_array_new_specific (array_vtable, 0);
klass = startklass = mono_class_from_mono_type (type->type);
len = 0;
if (name != NULL) {
mname = mono_string_to_utf8 (name);
- compare_func = (ignore_case) ? g_strcasecmp : strcmp;
+ compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
+ }
+
+ /* An optimization for calls made from Delegate:CreateDelegate () */
+ if (klass->delegate && mname && !strcmp (mname, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
+ method = mono_get_delegate_invoke (klass);
+ if (mono_loader_get_last_error ())
+ goto loader_error;
+
+ member = (MonoObject*)mono_method_get_object (domain, method, refklass);
+
+ res = mono_array_new_specific (array_vtable, 1);
+ mono_array_setref (res, 0, member);
+ g_free (mname);
+ return res;
}
mono_class_setup_vtable (klass);
+ if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+ goto loader_error;
if (is_generic_parameter (type->type))
- nslots = klass->parent->vtable_size;
+ nslots = mono_class_get_vtable_size (klass->parent);
else
- nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
+ nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
if (nslots >= sizeof (method_slots_default) * 8) {
method_slots = g_new0 (guint32, nslots / 32 + 1);
} else {
method_slots = method_slots_default;
memset (method_slots, 0, sizeof (method_slots_default));
}
- i = 0;
- len = 1;
- res = mono_array_new_specific (array_vtable, 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));
+ if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+ goto loader_error;
iter = NULL;
while ((method = mono_class_get_methods (klass, &iter))) {
match = 0;
+ if (method->slot != -1) {
+ g_assert (method->slot < nslots);
+ if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
+ continue;
+ method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
+ }
+
if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
continue;
if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
}
match = 0;
- if (method->slot != -1) {
- g_assert (method->slot < nslots);
- if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
- continue;
- method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
- }
member = (MonoObject*)mono_method_get_object (domain, method, refklass);
- if (i >= len) {
- MonoArray *new_res = mono_array_new_specific (array_vtable, len * 2);
- mono_array_memcpy_refs (new_res, 0, res, 0, len);
- len *= 2;
- res = new_res;
- }
- mono_array_setref (res, i, member);
- ++i;
+ mono_ptr_array_append (tmp_array, member);
}
if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
goto handle_parent;
g_free (mname);
if (method_slots != method_slots_default)
g_free (method_slots);
- if (i != len) {
- MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
- mono_array_memcpy_refs (new_res, 0, res, 0, i);
- res = new_res;
- /*
- * Better solution for the new GC.
- * res->max_length = i;
- */
- }
+
+ res = mono_array_new_specific (array_vtable, mono_ptr_array_size (tmp_array));
+
+ for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+ mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+ mono_ptr_array_destroy (tmp_array);
return res;
+
+loader_error:
+ g_free (mname);
+ if (method_slots != method_slots_default)
+ g_free (method_slots);
+ 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 MonoArray*
MonoArray *res;
MonoMethod *method;
MonoObject *member;
- int i, len, match;
+ int i, match;
gpointer iter = NULL;
+ MonoPtrArray tmp_array;
MONO_ARCH_SAVE_REGS;
+ mono_ptr_array_init (tmp_array, 4); /*FIXME, guestimating*/
+
domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref)
- return mono_array_new (domain, mono_defaults.method_info_class, 0);
+ return mono_array_new_cached (domain, mono_defaults.method_info_class, 0);
klass = startklass = mono_class_from_mono_type (type->type);
refklass = mono_class_from_mono_type (reftype->type);
System_Reflection_ConstructorInfo = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
- i = 0;
- len = 2;
- res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
iter = NULL;
while ((method = mono_class_get_methods (klass, &iter))) {
match = 0;
continue;
member = (MonoObject*)mono_method_get_object (domain, method, refklass);
- if (i >= len) {
- MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
- mono_array_memcpy_refs (new_res, 0, res, 0, len);
- len *= 2;
- res = new_res;
- }
- mono_array_setref (res, i, member);
- ++i;
- }
- if (i != len) {
- MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
- mono_array_memcpy_refs (new_res, 0, res, 0, i);
- res = new_res;
- /*
- * Better solution for the new GC.
- * res->max_length = i;
- */
+ mono_ptr_array_append (tmp_array, member);
}
+
+ res = mono_array_new_cached (domain, System_Reflection_ConstructorInfo, mono_ptr_array_size (tmp_array));
+
+ for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+ mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+ mono_ptr_array_destroy (tmp_array);
+
return res;
}
MonoMethod *method;
MonoProperty *prop;
int i, match;
- int len = 0;
guint32 flags;
gchar *propname = NULL;
int (*compare_func) (const char *s1, const char *s2) = NULL;
gpointer iter;
GHashTable *properties;
+ MonoPtrArray tmp_array;
MONO_ARCH_SAVE_REGS;
+ mono_ptr_array_init (tmp_array, 8); /*This the average for ASP.NET types*/
+
if (!System_Reflection_PropertyInfo)
System_Reflection_PropertyInfo = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "PropertyInfo");
domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref)
- return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
+ 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) ? g_strcasecmp : strcmp;
+ compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
}
mono_class_setup_vtable (klass);
properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
- i = 0;
- len = 2;
- res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
handle_parent:
mono_class_setup_vtable (klass);
if (klass->exception_type != MONO_EXCEPTION_NONE) {
if (g_hash_table_lookup (properties, prop))
continue;
- if (i >= len) {
- MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
- mono_array_memcpy_refs (new_res, 0, res, 0, len);
- len *= 2;
- res = new_res;
- }
- mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
- ++i;
+ mono_ptr_array_append (tmp_array, mono_property_get_object (domain, startklass, prop));
g_hash_table_insert (properties, prop, prop);
}
g_hash_table_destroy (properties);
g_free (propname);
- if (i != len) {
- MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
- mono_array_memcpy_refs (new_res, 0, res, 0, i);
- res = new_res;
- /*
- * Better solution for the new GC.
- * res->max_length = i;
- */
- }
+
+ res = mono_array_new_cached (domain, System_Reflection_PropertyInfo, mono_ptr_array_size (tmp_array));
+ for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+ mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+ mono_ptr_array_destroy (tmp_array);
+
return res;
}
if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
continue;
}
- }
- else
- if (!(bflags & BFLAGS_NonPublic))
- continue;
- if (method->flags & METHOD_ATTRIBUTE_STATIC) {
- if (!(bflags & BFLAGS_Static))
- continue;
- if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
- continue;
- } else {
- if (!(bflags & BFLAGS_Instance))
+ if (method->flags & METHOD_ATTRIBUTE_STATIC) {
+ if (!(bflags & BFLAGS_Static))
+ continue;
+ if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
+ continue;
+ } else {
+ if (!(bflags & BFLAGS_Instance))
+ continue;
+ }
+ } else
+ if (!(bflags & BFLAGS_NonPublic))
continue;
- }
-
+
g_free (event_name);
return mono_event_get_object (domain, startklass, event);
}
MonoArray *res;
MonoMethod *method;
MonoEvent *event;
- int i, len, match;
+ int i, match;
gpointer iter;
+
+ MonoPtrArray tmp_array;
MONO_ARCH_SAVE_REGS;
+ mono_ptr_array_init (tmp_array, 4);
+
if (!System_Reflection_EventInfo)
System_Reflection_EventInfo = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "EventInfo");
domain = mono_object_domain (type);
if (type->type->byref)
- return mono_array_new (domain, System_Reflection_EventInfo, 0);
+ return mono_array_new_cached (domain, System_Reflection_EventInfo, 0);
klass = startklass = mono_class_from_mono_type (type->type);
- i = 0;
- 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));
match ++;
if (!match)
continue;
- match = 0;
- if (i >= len) {
- MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
- mono_array_memcpy_refs (new_res, 0, res, 0, len);
- len *= 2;
- res = new_res;
- }
- mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
- ++i;
+ mono_ptr_array_append (tmp_array, mono_event_get_object (domain, startklass, event));
}
if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
goto handle_parent;
- if (i != len) {
- MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
- mono_array_memcpy_refs (new_res, 0, res, 0, i);
- res = new_res;
- /*
- * Better solution for the new GC.
- * res->max_length = i;
- */
- }
+
+ res = mono_array_new_cached (domain, System_Reflection_EventInfo, mono_ptr_array_size (tmp_array));
+
+ for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+ mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+ mono_ptr_array_destroy (tmp_array);
+
return res;
}
MONO_ARCH_SAVE_REGS;
+ if (name == NULL)
+ mono_raise_exception (mono_get_exception_argument_null ("name"));
+
domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref)
return NULL;
MonoClass *klass;
MonoArray *res;
MonoObject *member;
- int i, len, match;
+ int i, match;
MonoClass *nested;
gpointer iter;
+ MonoPtrArray tmp_array;
MONO_ARCH_SAVE_REGS;
if (klass->generic_class)
klass = klass->generic_class->container_class;
- i = 0;
- len = 1;
- res = mono_array_new (domain, mono_defaults.monotype_class, len);
+ mono_ptr_array_init (tmp_array, 1);
iter = NULL;
while ((nested = mono_class_get_nested_types (klass, &iter))) {
match = 0;
if (!match)
continue;
member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
- if (i >= len) {
- MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
- mono_array_memcpy_refs (new_res, 0, res, 0, len);
- len *= 2;
- res = new_res;
- }
- mono_array_setref (res, i, member);
- ++i;
- }
- if (i != len) {
- MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
- mono_array_memcpy_refs (new_res, 0, res, 0, i);
- res = new_res;
- /*
- * Better solution for the new GC.
- * res->max_length = i;
- */
+ mono_ptr_array_append (tmp_array, member);
}
+
+ res = mono_array_new_cached (domain, mono_defaults.monotype_class, mono_ptr_array_size (tmp_array));
+
+ for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+ mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+ mono_ptr_array_destroy (tmp_array);
+
return res;
}
if (throwOnError)
e = mono_get_exception_type_load (name, NULL);
+ if (mono_loader_get_last_error () && mono_defaults.generic_ilist_class)
+ e = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+
mono_loader_clear_error ();
if (e != NULL)
return mono_type_get_object (mono_object_domain (assembly), type);
}
-static MonoString *
-ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
+static gboolean
+replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
{
- MonoDomain *domain = mono_object_domain (assembly);
- MonoAssembly *mass = assembly->assembly;
- MonoString *res = NULL;
- gchar *uri;
- gchar *absolute;
gchar *content;
gchar *shadow_ini_file;
gsize len;
- gchar *dirname;
-
- MONO_ARCH_SAVE_REGS;
-
- if (g_path_is_absolute (mass->image->name)) {
- absolute = g_strdup (mass->image->name);
- dirname = g_path_get_dirname (absolute);
- } else {
- absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
- dirname = g_strdup (mass->basedir);
- }
/* Check for shadow-copied assembly */
if (mono_is_shadow_copy_enabled (domain, dirname)) {
}
g_free (shadow_ini_file);
if (content != NULL) {
- g_free (absolute);
- absolute = content;
+ if (*filename)
+ g_free (*filename);
+ *filename = content;
+ return TRUE;
}
}
- g_free (dirname);
+ return FALSE;
+}
+
+static MonoString *
+ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
+{
+ MonoDomain *domain = mono_object_domain (assembly);
+ MonoAssembly *mass = assembly->assembly;
+ MonoString *res = NULL;
+ gchar *uri;
+ gchar *absolute;
+ gchar *dirname;
+
+ MONO_ARCH_SAVE_REGS;
+
+ if (g_path_is_absolute (mass->image->name)) {
+ absolute = g_strdup (mass->image->name);
+ dirname = g_path_get_dirname (absolute);
+ } else {
+ absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
+ dirname = g_strdup (mass->basedir);
+ }
-#if PLATFORM_WIN32
+ replace_shadow_path (domain, dirname, &absolute);
+ g_free (dirname);
+#if HOST_WIN32
{
gint i;
for (i = strlen (absolute) - 1; i >= 0; i--)
uri = g_filename_to_uri (absolute, NULL, NULL);
} else {
const char *prepend = "file://";
-#if PLATFORM_WIN32
+#if HOST_WIN32
if (*absolute == '/' && *(absolute + 1) == '/') {
prepend = "file:";
} else {
result = mono_array_new (domain, System_Reflection_AssemblyName, count);
- if (count > 0) {
+ if (count > 0 && !create_culture) {
MonoMethodDesc *desc = mono_method_desc_new (
"System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
MonoImage *img = assembly->assembly->image;
MonoArray *res;
NameSpaceInfo info;
+ int len;
MONO_ARCH_SAVE_REGS;
- if (!img->name_cache)
- mono_image_init_name_cache (img);
+ mono_image_lock (img);
+ mono_image_init_name_cache (img);
+
+RETRY_LEN:
+ len = g_hash_table_size (img->name_cache);
+ mono_image_unlock (img);
+
+ /*we can't create objects holding the image lock */
+ res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, len);
+
+ mono_image_lock (img);
+ /*len might have changed, create a new array*/
+ if (len != g_hash_table_size (img->name_cache))
+ goto RETRY_LEN;
- res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
info.res = res;
info.idx = 0;
g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
+ mono_image_unlock (img);
return res;
}
else
module = assembly->assembly->image;
- *ref_module = mono_module_get_object (mono_domain_get (), module);
+ mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) mono_module_get_object (mono_domain_get (), module));
return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
}
{
MonoMethod *m = mono_method_get_last_managed ();
- MONO_ARCH_SAVE_REGS;
+ while (m->is_inflated)
+ m = ((MonoMethodInflated*)m)->declaring;
return mono_method_get_object (mono_domain_get (), m, NULL);
}
codebase = g_strdup (absolute);
-#if PLATFORM_WIN32
+#if HOST_WIN32
{
gint i;
for (i = strlen (codebase) - 1; i >= 0; i--)
gboolean res;
MonoImage *image;
MonoAssemblyName name;
+ char *dirname
MONO_ARCH_SAVE_REGS;
filename = mono_string_to_utf8 (fname);
+ dirname = g_path_get_dirname (filename);
+ replace_shadow_path (mono_domain_get (), dirname, &filename);
+ g_free (dirname);
+
image = mono_image_open (filename, &status);
if (!image){
static gpointer
ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
{
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
if (module->image && module->image->is_module_handle)
return module->image->raw_data;
#endif
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type);
- aklass = mono_array_class_get (klass, rank);
+ if (rank == 0) //single dimentional array
+ aklass = mono_array_class_get (klass, 1);
+ else
+ aklass = mono_bounded_array_class_get (klass, rank, TRUE);
return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
}
static MonoObject *
ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
- MonoReflectionMethod *info)
+ MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
{
MonoClass *delegate_class = mono_class_from_mono_type (type->type);
MonoObject *delegate;
mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
- /* FIME: We must check if target is visible to the caller under coreclr.
- * The check should be disabled otherwise as it shouldn't raise expection under fulltrust.
- */
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ if (!mono_security_core_clr_ensure_delegate_creation (method, throwOnBindFailure))
+ return NULL;
+ }
delegate = mono_object_new (mono_object_domain (type), delegate_class);
- if (mono_method_needs_static_rgctx_invoke (method, FALSE)) {
- method = mono_marshal_get_static_rgctx_invoke (method);
- func = mono_compile_method (method);
- } else if (method->dynamic) {
+ if (method->dynamic) {
/* Creating a trampoline would leak memory */
func = mono_compile_method (method);
} else {
*/
#define FILETIME_ADJUST ((guint64)504911232000000000LL)
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
/* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
static void
convert_to_absolute_date(SYSTEMTIME *date)
}
#endif
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
/*
* Return's the offset from GMT of a local time.
*
static guint32
ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
{
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
MonoDomain *domain = mono_domain_get ();
struct tm start, tt;
time_t t;
MONO_CHECK_ARG_NULL (data);
MONO_CHECK_ARG_NULL (names);
- (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
- (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+ mono_gc_wbarrier_generic_store (data, (MonoObject*) mono_array_new (domain, mono_defaults.int64_class, 4));
+ mono_gc_wbarrier_generic_store (names, (MonoObject*) mono_array_new (domain, mono_defaults.string_class, 2));
/*
* no info is better than crashing: we'll need our own tz data
MONO_CHECK_ARG_NULL (data);
MONO_CHECK_ARG_NULL (names);
- (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
- (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+ mono_gc_wbarrier_generic_store (data, mono_array_new (domain, mono_defaults.int64_class, 4));
+ mono_gc_wbarrier_generic_store (names, mono_array_new (domain, mono_defaults.string_class, 2));
for (i = 0; i < 32; ++i)
if (!tz_info.DaylightName [i])
/* System.Environment */
+MonoString*
+ves_icall_System_Environment_get_UserName (void)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ /* using glib is more portable */
+ return mono_string_new (mono_domain_get (), g_get_user_name ());
+}
+
+
static MonoString *
ves_icall_System_Environment_get_MachineName (void)
{
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
gunichar2 *buf;
guint32 len;
MonoString *result;
g_free (buf);
return result;
-#else
+#elif !defined(DISABLE_SOCKETS)
gchar buf [256];
MonoString *result;
result = NULL;
return result;
+#else
+ return mono_string_new (mono_domain_get (), "mono");
#endif
}
static int
ves_icall_System_Environment_get_Platform (void)
{
-#if defined (PLATFORM_WIN32)
+#if defined (TARGET_WIN32)
/* Win32NT */
return 2;
#elif defined(__MACH__)
{
MONO_ARCH_SAVE_REGS;
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
return mono_string_new (mono_domain_get (), "\r\n");
#else
return mono_string_new (mono_domain_get (), "\n");
* arm-apple-darwin9. We'll manually define the symbol on Apple as it does
* in fact exist on all implementations (so far)
*/
-gchar ***_NSGetEnviron();
+gchar ***_NSGetEnviron(void);
#define environ (*_NSGetEnviron())
#else
extern
static MonoArray *
ves_icall_System_Environment_GetEnvironmentVariableNames (void)
{
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
MonoArray *names;
MonoDomain *domain;
MonoString *str;
static void
ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
{
-#ifdef PLATFORM_WIN32
+ MonoError error;
+#ifdef HOST_WIN32
+
gunichar2 *utf16_name, *utf16_value;
#else
gchar *utf8_name, *utf8_value;
MONO_ARCH_SAVE_REGS;
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
utf16_name = mono_string_to_utf16 (name);
if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
SetEnvironmentVariable (utf16_name, NULL);
return;
}
- utf8_value = mono_string_to_utf8 (value);
+ utf8_value = mono_string_to_utf8_checked (value, &error);
+ if (!mono_error_ok (&error)) {
+ g_free (utf8_name);
+ mono_error_raise_exception (&error);
+ }
g_setenv (utf8_name, utf8_value, TRUE);
g_free (utf8_name);
static MonoString*
ves_icall_System_Environment_GetWindowsFolderPath (int folder)
{
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
#ifndef CSIDL_FLAG_CREATE
#define CSIDL_FLAG_CREATE 0x8000
#endif
static void
ves_icall_System_Environment_BroadcastSettingChange (void)
{
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, NULL, L"Environment", SMTO_ABORTIFHUNG, 2000, 0);
#endif
}
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type);
- vtable = mono_class_vtable (mono_domain_get (), klass);
+ vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE);
if (enable) vtable->remote = 1;
else vtable->remote = 0;
return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
} else {
/* Bypass remoting object creation check */
- return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
+ return mono_object_new_alloc_specific (mono_class_vtable_full (domain, klass, TRUE));
}
}
return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
}
+#ifndef PLATFORM_NO_DRIVEINFO
+static MonoBoolean
+ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
+ guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
+ gint32 *error)
+{
+ gboolean result;
+ ULARGE_INTEGER wapi_free_bytes_avail;
+ ULARGE_INTEGER wapi_total_number_of_bytes;
+ ULARGE_INTEGER wapi_total_number_of_free_bytes;
+
+ MONO_ARCH_SAVE_REGS;
+
+ *error = ERROR_SUCCESS;
+ result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
+ &wapi_total_number_of_free_bytes);
+
+ if (result) {
+ *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
+ *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
+ *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
+ } else {
+ *free_bytes_avail = 0;
+ *total_number_of_bytes = 0;
+ *total_number_of_free_bytes = 0;
+ *error = GetLastError ();
+ }
+
+ return result;
+}
+
+static guint32
+ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ return GetDriveType (mono_string_chars (root_path_name));
+}
+#endif
+
static gpointer
ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
{
path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
/* Avoid mixing '/' and '\\' */
{
gint i;
path = g_path_get_dirname (mono_get_config_dir ());
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
/* Avoid mixing '/' and '\\' */
{
gint i;
return ipath;
}
+static gboolean
+ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
+{
+ MonoPEResourceDataEntry *entry;
+ MonoImage *image;
+
+ MONO_ARCH_SAVE_REGS;
+
+ if (!assembly || !result || !size)
+ return FALSE;
+
+ *result = NULL;
+ *size = 0;
+ image = assembly->assembly->image;
+ entry = mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
+ if (!entry)
+ return FALSE;
+
+ *result = mono_image_rva_map (image, entry->rde_data_offset);
+ if (!(*result)) {
+ g_free (entry);
+ return FALSE;
+ }
+ *size = entry->rde_size;
+ g_free (entry);
+ return TRUE;
+}
+
static MonoBoolean
ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
{
- return mono_debug_using_mono_debugger ();
+ return mono_debug_using_mono_debugger () || mono_is_debugger_attached ();
}
static void
ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
{
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
OutputDebugString (mono_string_chars (message));
#else
- g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
+ g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
#endif
}
}
static MonoReflectionMethod *
-ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
+ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
{
MonoClass *klass, *parent;
MonoMethod *method = m->method;
if (klass->generic_class)
klass = klass->generic_class->container_class;
- /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
- for (parent = klass->parent; parent != NULL; parent = parent->parent) {
- mono_class_setup_vtable (parent);
- if (parent->vtable_size <= method->slot)
- break;
- klass = parent;
- }
+ if (definition) {
+ /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
+ for (parent = klass->parent; parent != NULL; parent = parent->parent) {
+ mono_class_setup_vtable (parent);
+ if (parent->vtable_size <= method->slot)
+ break;
+ klass = parent;
+ }
+ } else {
+ klass = klass->parent;
+ if (!klass)
+ return m;
+ }
if (klass == method->klass)
return m;
if (start) {
iter->args = start;
} else {
- guint32 i, arg_size;
- gint32 align;
iter->args = argsp + sizeof (gpointer);
-#ifndef MONO_ARCH_REGPARMS
- for (i = 0; i < iter->sig->sentinelpos; ++i) {
- arg_size = mono_type_stack_size (iter->sig->params [i], &align);
- iter->args = (char*)iter->args + arg_size;
- }
-#endif
}
iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
if (mono_loader_get_last_error ()) {
mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
g_assert_not_reached ();
+ /* Not reached */
+ return NULL;
} else {
return res;
}
}
-static MonoBoolean
-GCHandle_CheckCurrentDomain (guint32 gchandle)
-{
- return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
-}
-
static MonoString*
ves_icall_Mono_Runtime_GetDisplayName (void)
{
- static const char display_name_str [] = "Mono " VERSION;
- MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
+ char *info;
+ MonoString *display_name;
+
+ info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
+ display_name = mono_string_new (mono_domain_get (), info);
+ g_free (info);
return display_name;
}
else if (!strcmp (typename, "boolean"))
klass = mono_defaults.boolean_class;
else {
- g_error (typename);
+ g_error ("%s", typename);
g_assert_not_reached ();
}
return &klass->byval_arg;
res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
res->pinvoke = 1;
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
/*
* Under windows, the default pinvoke calling convention is STDCALL but
* we need CDECL.