#include <mono/metadata/threads.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/threadpool.h>
+#include <mono/metadata/threadpool-microsoft.h>
#include <mono/metadata/monitor.h>
#include <mono/metadata/reflection.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/verify-internals.h>
#include <mono/metadata/runtime.h>
#include <mono/metadata/file-mmap.h>
+#include <mono/metadata/seq-points-data.h>
#include <mono/io-layer/io-layer.h>
#include <mono/utils/strtod.h>
#include <mono/utils/monobitset.h>
#endif
#include "decimal-ms.h"
-extern MonoString* ves_icall_System_Environment_GetOSVersionString (void) MONO_INTERNAL;
+extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
INVALID_CAST;
}
break;
+ default:
+ break;
}
if (!ec->valuetype) {
return mono_type_get_object (domain, handle);
}
-ICALL_EXPORT MonoBoolean
-ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
-{
- if (c && type->type && c->type)
- return mono_metadata_type_equal (type->type, c->type);
- else
- return (type == c) ? TRUE : FALSE;
-}
-
/* System.TypeCode */
typedef enum {
TYPECODE_EMPTY,
return 0;
}
-ICALL_EXPORT guint32
-ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
-{
- MonoDomain *domain;
- MonoClass *klass;
- MonoClass *klassc;
-
- g_assert (type != NULL);
-
- domain = ((MonoObject *)type)->vtable->domain;
-
- if (!c) /* FIXME: dont know what do do here */
- return 0;
-
- klass = mono_class_from_mono_type (type->type);
- klassc = mono_class_from_mono_type (c->type);
-
- /* Interface check requires a more complex setup so we
- * only do for them. Otherwise we simply avoid mono_class_init.
- */
- if (check_interfaces) {
- mono_class_init_or_throw (klass);
- mono_class_init_or_throw (klassc);
- } else if (!klass->supertypes || !klassc->supertypes) {
- mono_class_setup_supertypes (klass);
- mono_class_setup_supertypes (klassc);
- }
-
- if (type->type->byref)
- return klassc == mono_defaults.object_class;
-
- return mono_class_is_subclass_of (klass, klassc, check_interfaces);
-}
-
static gboolean
mono_type_is_primitive (MonoType *type)
{
ICALL_EXPORT guint32
ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
{
- MonoDomain *domain;
MonoClass *klass;
MonoClass *klassc;
g_assert (type != NULL);
- domain = ((MonoObject *)type)->vtable->domain;
-
klass = mono_class_from_mono_type (type->type);
klassc = mono_class_from_mono_type (c->type);
ICALL_EXPORT MonoReflectionType*
ves_icall_get_type_parent (MonoReflectionType *type)
{
+ if (type->type->byref)
+ return NULL;
+
MonoClass *class = mono_class_from_mono_type (type->type);
return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
}
return mono_type_get_object (mono_object_domain (type), geninst);
}
-ICALL_EXPORT gboolean
-ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
-{
- MonoClass *klass;
-
- if (type->type->byref)
- return FALSE;
-
- klass = mono_class_from_mono_type (type->type);
-
- return klass->generic_class != NULL;
-}
-
ICALL_EXPORT gboolean
ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
{
#endif
static guint64
-read_enum_value (char *mem, int type)
+read_enum_value (const char *mem, int type)
{
switch (type) {
case MONO_TYPE_BOOLEAN:
return *(gint8*)mem;
case MONO_TYPE_CHAR:
case MONO_TYPE_U2:
- return *(guint16*)mem;
+ return read16 (mem);
case MONO_TYPE_I2:
- return *(gint16*)mem;
+ return (gint16) read16 (mem);
case MONO_TYPE_U4:
- return *(guint32*)mem;
+ return read32 (mem);
case MONO_TYPE_I4:
- return *(gint32*)mem;
+ return (gint32) read32 (mem);
case MONO_TYPE_U8:
- return *(guint64*)mem;
case MONO_TYPE_I8:
- return *(gint64*)mem;
+ return read64 (mem);
default:
g_assert_not_reached ();
}
}
ICALL_EXPORT MonoObject *
-ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
+ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
{
MonoDomain *domain;
- MonoClass *enumc, *objc;
+ MonoClass *enumc;
MonoObject *res;
MonoType *etype;
- guint64 val;
-
- MONO_CHECK_ARG_NULL (enumType, NULL);
- MONO_CHECK_ARG_NULL (value, NULL);
domain = mono_object_domain (enumType);
enumc = mono_class_from_mono_type (enumType->type);
mono_class_init_or_throw (enumc);
- objc = value->vtable->klass;
-
- if (!enumc->enumtype) {
- mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
- return NULL;
- }
- if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_BOOLEAN && objc->byval_arg.type <= MONO_TYPE_U8))) {
- mono_set_pending_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."));
- return NULL;
- }
-
etype = mono_class_enum_basetype (enumc);
- if (!etype) {
- /* MS throws this for typebuilders */
- mono_set_pending_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
- return NULL;
- }
res = mono_object_new (domain, enumc);
- val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? mono_class_enum_basetype (objc)->type: objc->byval_arg.type);
- write_enum_value ((char *)res + sizeof (MonoObject), etype->type, val);
+ write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
return res;
}
etype = mono_class_enum_basetype (klass);
if (!etype) {
- /* MS throws this for typebuilders */
- mono_set_pending_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
+ mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
return NULL;
}
MonoType *basetype = mono_class_enum_basetype (this->vtable->klass);
g_assert (basetype);
+ if (other == NULL)
+ return 1;
+
+ if (this->vtable->klass != other->vtable->klass)
+ return 2;
+
#define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
ENUM_TYPE other = *((ENUM_TYPE*)odata); \
case MONO_TYPE_I8:
COMPARE_ENUM_VALUES (gint64);
default:
- g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
+ break;
}
#undef COMPARE_ENUM_VALUES
- return 0;
+ /* indicates that the enum was of an unsupported unerlying type */
+ return 3;
}
ICALL_EXPORT int
return 0;
}
-ICALL_EXPORT void
-ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
+ICALL_EXPORT MonoBoolean
+ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionType *type, MonoArray **values, MonoArray **names)
{
MonoDomain *domain = mono_object_domain (type);
MonoClass *enumc = mono_class_from_mono_type (type->type);
- guint j = 0, nvalues, crow;
+ guint j = 0, nvalues;
gpointer iter;
MonoClassField *field;
+ int base_type;
+ guint64 field_value, previous_value = 0;
+ gboolean sorted = TRUE;
mono_class_init_or_throw (enumc);
- MONO_STRUCT_SETREF (info, utype, mono_type_get_object (domain, mono_class_enum_basetype (enumc)));
+ if (!enumc->enumtype) {
+ mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
+ return TRUE;
+ }
+
+ base_type = mono_class_enum_basetype (enumc)->type;
+
nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
- MONO_STRUCT_SETREF (info, names, mono_array_new (domain, mono_defaults.string_class, nvalues));
- MONO_STRUCT_SETREF (info, values, mono_array_new (domain, enumc, nvalues));
+ *names = mono_array_new (domain, mono_defaults.string_class, nvalues);
+ *values = mono_array_new (domain, mono_defaults.uint64_class, nvalues);
- crow = -1;
iter = NULL;
while ((field = mono_class_get_fields (enumc, &iter))) {
const char *p;
- int len;
MonoTypeEnum def_type;
-
+
if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
continue;
if (strcmp ("value__", mono_field_get_name (field)) == 0)
continue;
if (mono_field_is_deleted (field))
continue;
- mono_array_setref (info->names, j, mono_string_new (domain, mono_field_get_name (field)));
+ mono_array_setref (*names, j, mono_string_new (domain, mono_field_get_name (field)));
p = mono_class_get_field_default_value (field, &def_type);
- len = mono_metadata_decode_blob_size (p, &p);
- switch (mono_class_enum_basetype (enumc)->type) {
- case MONO_TYPE_U1:
- case MONO_TYPE_I1:
- mono_array_set (info->values, gchar, j, *p);
- break;
- case MONO_TYPE_CHAR:
- case MONO_TYPE_U2:
- case MONO_TYPE_I2:
- mono_array_set (info->values, gint16, j, read16 (p));
- break;
- case MONO_TYPE_U4:
- case MONO_TYPE_I4:
- mono_array_set (info->values, gint32, j, read32 (p));
- break;
- case MONO_TYPE_U8:
- case MONO_TYPE_I8:
- mono_array_set (info->values, gint64, j, read64 (p));
- break;
- default:
- g_error ("Implement type 0x%02x in get_enum_info", mono_class_enum_basetype (enumc)->type);
- }
+ /* len = */ mono_metadata_decode_blob_size (p, &p);
+
+ field_value = read_enum_value (p, base_type);
+ mono_array_set (*values, guint64, j, field_value);
+
+ if (previous_value > field_value)
+ sorted = FALSE;
+
+ previous_value = field_value;
++j;
}
+
+ return sorted;
}
enum {
BFLAGS_OptionalParamBinding = 0x40000
};
-ICALL_EXPORT MonoReflectionField *
-ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
-{
- MonoDomain *domain;
- MonoClass *startklass, *klass;
- int match;
- MonoClassField *field;
- gpointer iter;
- char *utf8_name;
- int (*compare_func) (const char *s1, const char *s2) = NULL;
- domain = ((MonoObject *)type)->vtable->domain;
- klass = startklass = mono_class_from_mono_type (type->type);
-
- if (!name) {
- mono_set_pending_exception (mono_get_exception_argument_null ("name"));
- return NULL;
- }
- if (type->type->byref)
- return NULL;
-
- compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-
-handle_parent:
- if (klass->exception_type != MONO_EXCEPTION_NONE) {
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
- return NULL;
- }
-
- iter = NULL;
- while ((field = mono_class_get_fields_lazy (klass, &iter))) {
- guint32 flags = mono_field_get_flags (field);
- match = 0;
-
- if (mono_field_is_deleted_with_flags (field, flags))
- continue;
- if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
- if (bflags & BFLAGS_Public)
- match++;
- } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
- if (bflags & BFLAGS_NonPublic) {
- match++;
- }
- }
- if (!match)
- continue;
- match = 0;
- if (flags & FIELD_ATTRIBUTE_STATIC) {
- if (bflags & BFLAGS_Static)
- if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
- match++;
- } else {
- if (bflags & BFLAGS_Instance)
- match++;
- }
-
- if (!match)
- continue;
-
- utf8_name = mono_string_to_utf8 (name);
-
- if (compare_func (mono_field_get_name (field), utf8_name)) {
- g_free (utf8_name);
- continue;
- }
- g_free (utf8_name);
-
- return mono_field_get_object (domain, klass, field);
- }
- if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
- goto handle_parent;
-
- return NULL;
-}
-
ICALL_EXPORT MonoArray*
-ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
+ves_icall_Type_GetFields_internal (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoReflectionType *reftype)
{
MonoDomain *domain;
MonoClass *startklass, *klass, *refklass;
MonoObject *member;
int i, match;
gpointer iter;
+ char *utf8_name = NULL;
+ int (*compare_func) (const char *s1, const char *s2) = NULL;
MonoClassField *field;
MonoPtrArray tmp_array;
domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref)
return mono_array_new (domain, mono_defaults.field_info_class, 0);
+
klass = startklass = mono_class_from_mono_type (type->type);
refklass = mono_class_from_mono_type (reftype->type);
if (!match)
continue;
+
+ if (name != NULL) {
+ if (utf8_name == NULL) {
+ utf8_name = mono_string_to_utf8 (name);
+ compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+ }
+
+ if (compare_func (mono_field_get_name (field), utf8_name))
+ continue;
+ }
+
member = (MonoObject*)mono_field_get_object (domain, refklass, field);
mono_ptr_array_append (tmp_array, member);
}
mono_ptr_array_destroy (tmp_array);
+ if (utf8_name != NULL)
+ g_free (utf8_name);
+
return res;
}
MonoClass *startklass;
MonoMethod *method;
gpointer iter;
- int len, match, nslots;
+ int match, nslots;
/*FIXME, use MonoBitSet*/
guint32 method_slots_default [8];
guint32 *method_slots = NULL;
startklass = klass;
*ex = NULL;
- len = 0;
if (name != NULL)
compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
return NULL;
}
-ICALL_EXPORT MonoReflectionEvent *
-ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
-{
- MonoDomain *domain;
- MonoClass *klass, *startklass;
- gpointer iter;
- MonoEvent *event;
- MonoMethod *method;
- gchar *event_name;
- int (*compare_func) (const char *s1, const char *s2);
-
- event_name = mono_string_to_utf8 (name);
- if (type->type->byref)
- return NULL;
- klass = startklass = mono_class_from_mono_type (type->type);
- domain = mono_object_domain (type);
-
- mono_class_init_or_throw (klass);
-
- compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-handle_parent:
- if (klass->exception_type != MONO_EXCEPTION_NONE) {
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
- return NULL;
- }
-
- iter = NULL;
- while ((event = mono_class_get_events (klass, &iter))) {
- if (compare_func (event->name, event_name))
- continue;
-
- method = event->add;
- if (!method)
- method = event->remove;
- if (!method)
- method = event->raise;
- if (method) {
- if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
- if (!(bflags & BFLAGS_Public))
- continue;
- } else {
- if (!(bflags & BFLAGS_NonPublic))
- continue;
- if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
- continue;
- }
-
- 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);
- }
-
- if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
- goto handle_parent;
-
- g_free (event_name);
- return NULL;
-}
-
static guint
event_hash (gconstpointer data)
{
}
ICALL_EXPORT MonoArray*
-ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
+ves_icall_Type_GetEvents_internal (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoReflectionType *reftype)
{
MonoException *ex;
MonoDomain *domain;
MonoEvent *event;
int i, match;
gpointer iter;
+ char *utf8_name = NULL;
+ int (*compare_func) (const char *s1, const char *s2) = NULL;
GHashTable *events = NULL;
MonoPtrArray tmp_array;
if (!match)
continue;
+ if (name != NULL) {
+ if (utf8_name == NULL) {
+ utf8_name = mono_string_to_utf8 (name);
+ compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+ }
+
+ if (compare_func (event->name, utf8_name))
+ continue;
+ }
+
if (g_hash_table_lookup (events, event))
continue;
mono_ptr_array_destroy (tmp_array);
+ if (utf8_name != NULL)
+ g_free (utf8_name);
+
return res;
loader_error:
return NULL;
}
-ICALL_EXPORT MonoReflectionType *
-ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
-{
- MonoDomain *domain;
- MonoClass *klass;
- MonoClass *nested;
- char *str;
- gpointer iter;
-
- if (name == NULL) {
- mono_set_pending_exception (mono_get_exception_argument_null ("name"));
- return NULL;
- }
-
- domain = ((MonoObject *)type)->vtable->domain;
- if (type->type->byref)
- return NULL;
- klass = mono_class_from_mono_type (type->type);
-
- str = mono_string_to_utf8 (name);
-
- handle_parent:
- if (klass->exception_type != MONO_EXCEPTION_NONE) {
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
- return NULL;
- }
-
- /*
- * 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;
-
- iter = NULL;
- while ((nested = mono_class_get_nested_types (klass, &iter))) {
- int match = 0;
- if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
- if (bflags & BFLAGS_Public)
- match++;
- } else {
- if (bflags & BFLAGS_NonPublic)
- match++;
- }
- if (!match)
- continue;
- if (strcmp (nested->name, str) == 0){
- g_free (str);
- return mono_type_get_object (domain, &nested->byval_arg);
- }
- }
- if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
- goto handle_parent;
- g_free (str);
- return NULL;
-}
-
ICALL_EXPORT MonoArray*
-ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
+ves_icall_Type_GetNestedTypes (MonoReflectionType *type, MonoString *name, guint32 bflags)
{
MonoDomain *domain;
MonoClass *klass;
int i, match;
MonoClass *nested;
gpointer iter;
+ char *str = NULL;
MonoPtrArray tmp_array;
domain = ((MonoObject *)type)->vtable->domain;
}
if (!match)
continue;
+
+ if (name != NULL) {
+ if (str == NULL)
+ str = mono_string_to_utf8 (name);
+
+ if (strcmp (nested->name, str))
+ continue;
+ }
+
member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
mono_ptr_array_append (tmp_array, member);
}
mono_ptr_array_destroy (tmp_array);
+ if (!str)
+ g_free (str);
+
return res;
}
return mono_security_core_clr_class_level (klass);
}
+ICALL_EXPORT int
+ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *this)
+{
+ MonoClassField *field = this->field;
+ return mono_security_core_clr_field_level (field, TRUE);
+}
+
+ICALL_EXPORT int
+ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *this)
+{
+ MonoMethod *method = this->method;
+ return mono_security_core_clr_method_level (method, TRUE);
+}
+
static void
fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
{
}
transitioned++;
} else {
- time_t te;
- te = mktime (&tt);
-
mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
if (gmtoff_ds == 0) {
return message;
}
+ICALL_EXPORT int
+ves_icall_System_StackFrame_GetILOffsetFromFile (MonoString *path, int methodToken, int nativeOffset)
+{
+ guint32 il_offset;
+ char *path_str = mono_string_to_utf8 (path);
+
+ if (!seq_point_data_get_il_offset (path_str, methodToken, nativeOffset, &il_offset))
+ il_offset = -1;
+
+ g_free (path_str);
+
+ return il_offset;
+}
+
#ifndef DISABLE_ICALL_TABLES
#define ICALL_TYPE(id,name,first)