#include <stdlib.h>
#endif
+#include "mono/utils/mono-membar.h"
#include <mono/metadata/object.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/threads-types.h>
klass = mono_object_class (this);
+ if (klass->enumtype && klass->enum_basetype && klass->enum_basetype->type == MONO_TYPE_I4)
+ return (*(gint32*)((guint8*)this + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
+
/*
* Do the comparison for fields of primitive type and return a result if
* possible. Otherwise, return the remaining fields in an array to the
continue;
/* FIXME: Add more types */
switch (field->type->type) {
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_BOOLEAN:
+ if (*((guint8*)this + field->offset) != *((guint8*)that + field->offset))
+ return FALSE;
+ break;
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_CHAR:
+ if (*(gint16*)((guint8*)this + field->offset) != *(gint16*)((guint8*)that + field->offset))
+ return FALSE;
+ break;
+ case MONO_TYPE_U4:
case MONO_TYPE_I4:
if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
return FALSE;
break;
+ case MONO_TYPE_U8:
+ case MONO_TYPE_I8:
+ if (*(gint64*)((guint8*)this + field->offset) != *(gint64*)((guint8*)that + field->offset))
+ return FALSE;
+ break;
+ case MONO_TYPE_R4:
+ if (*(float*)((guint8*)this + field->offset) != *(float*)((guint8*)that + field->offset))
+ return FALSE;
+ break;
+ case MONO_TYPE_R8:
+ if (*(double*)((guint8*)this + field->offset) != *(double*)((guint8*)that + field->offset))
+ return FALSE;
+ break;
+
+
case MONO_TYPE_STRING: {
MonoString *s1, *s2;
guint32 s1len, s2len;
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)
{
}
if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) {
- *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class.");
+ *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
return NULL;
}
return res;
}
+static MonoReflectionType *
+ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ return mono_type_get_object (mono_object_domain (type), mono_class_from_mono_type (type->type)->enum_basetype);
+}
+
+static int
+ves_icall_System_Enum_get_hashcode (MonoObject *this)
+{
+ gpointer data = (char *)this + sizeof (MonoObject);
+ MonoType *basetype = this->vtable->klass->enum_basetype;
+ g_assert (basetype);
+
+ switch (basetype->type) {
+ case MONO_TYPE_I1:
+ return *((gint8*)data);
+ case MONO_TYPE_U1:
+ return *((guint8*)data);
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_U2:
+ return *((guint16*)data);
+
+ case MONO_TYPE_I2:
+ return *((gint16*)data);
+ case MONO_TYPE_U4:
+ return *((guint32*)data);
+ case MONO_TYPE_I4:
+ return *((gint32*)data);
+ case MONO_TYPE_U8:
+ case MONO_TYPE_I8: {
+ gint64 value = *((gint64*)data);
+ return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
+ }
+ default:
+ g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
+ }
+ return 0;
+}
+
static void
ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
{
static MonoArray*
ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
{
+ static MonoClass *MethodInfo_array;
MonoDomain *domain;
MonoClass *startklass, *klass, *refklass;
MonoArray *res;
guint32 *method_slots;
gchar *mname = NULL;
int (*compare_func) (const char *s1, const char *s2) = NULL;
+ MonoVTable *array_vtable;
MONO_ARCH_SAVE_REGS;
+ if (!MethodInfo_array) {
+ MonoClass *klass = mono_array_class_get (mono_defaults.method_info_class, 1);
+ mono_memory_barrier ();
+ MethodInfo_array = klass;
+ }
+
domain = ((MonoObject *)type)->vtable->domain;
+ array_vtable = mono_class_vtable (domain, MethodInfo_array);
if (type->type->byref)
- return mono_array_new (domain, mono_defaults.method_info_class, 0);
+ return mono_array_new_specific (array_vtable, 0);
klass = startklass = mono_class_from_mono_type (type->type);
refklass = mono_class_from_mono_type (reftype->type);
len = 0;
}
i = 0;
len = 1;
- res = mono_array_new (domain, mono_defaults.method_info_class, len);
+ res = mono_array_new_specific (array_vtable, len);
handle_parent:
mono_class_setup_vtable (klass);
if (klass->exception_type != MONO_EXCEPTION_NONE)
member = (MonoObject*)mono_method_get_object (domain, method, refklass);
if (i >= len) {
- MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
+ 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;
MonoDomain *domain;
MonoClass *klass;
MonoClass *nested;
- GList *tmpn;
char *str;
+ gpointer iter;
MONO_ARCH_SAVE_REGS;
if (klass->generic_class)
klass = klass->generic_class->container_class;
- for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
+ iter = NULL;
+ while ((nested = mono_class_get_nested_types (klass, &iter))) {
int match = 0;
- nested = tmpn->data;
if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
if (bflags & BFLAGS_Public)
match++;
ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
{
MonoDomain *domain;
- GList *tmpn;
MonoClass *klass;
MonoArray *res;
MonoObject *member;
int i, len, match;
MonoClass *nested;
+ gpointer iter;
MONO_ARCH_SAVE_REGS;
i = 0;
len = 1;
res = mono_array_new (domain, mono_defaults.monotype_class, len);
- for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
+ iter = NULL;
+ while ((nested = mono_class_get_nested_types (klass, &iter))) {
match = 0;
- nested = tmpn->data;
if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
if (bflags & BFLAGS_Public)
match++;
MonoString *res = NULL;
gchar *uri;
gchar *absolute;
+ gchar *dyn_base;
+ gchar *shadow_ini_file;
+ gsize len;
MONO_ARCH_SAVE_REGS;
- if (g_path_is_absolute (mass->image->name))
+ absolute = NULL;
+ /* Check for shadow-copied assembly */
+ if (domain->setup->dynamic_base != NULL) {
+ dyn_base = mono_string_to_utf8 (domain->setup->dynamic_base);
+ if (!strncmp (dyn_base, mass->basedir, strlen (dyn_base))) {
+ shadow_ini_file = g_build_filename (mass->basedir, "__AssemblyInfo__.ini", NULL);
+ if (!g_file_get_contents (shadow_ini_file, &absolute, &len, NULL) ||
+ !g_file_test (absolute, G_FILE_TEST_IS_REGULAR)) {
+ if (absolute) {
+ g_free (absolute);
+ absolute = NULL;
+ }
+ }
+ g_free (shadow_ini_file);
+ }
+ g_free (dyn_base);
+ /* 'absolute' contains the original location of the shadow-copied assembly or NULL */
+ }
+
+ if (absolute == NULL && g_path_is_absolute (mass->image->name))
absolute = g_strdup (mass->image->name);
- else
+ else if (absolute == NULL)
absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
+
#if PLATFORM_WIN32
{
gint i;
if (escaped) {
uri = g_filename_to_uri (absolute, NULL, NULL);
} else {
- uri = g_strconcat ("file://", absolute, NULL);
+ const char *prepend = "file://";
+#if PLATFORM_WIN32
+ if (*absolute == '/' && *(absolute + 1) == '/') {
+ prepend = "file:";
+ } else {
+ prepend = "file:///";
+ }
+#else
+ uri = g_strconcat (prepend, absolute, NULL);
+#endif
}
if (uri) {
if (create_culture) {
gpointer args [2];
- gboolean assembly_ref = TRUE;
+ MonoBoolean assembly_ref = 1;
args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
args [1] = &assembly_ref;
MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
{
int offset = -1, i;
if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
- MonoMethodInflated *inflated = method;
+ MonoMethodInflated *inflated = (MonoMethodInflated*)method;
//method is inflated, we should inflate it on the other class
MonoGenericContext ctx;
ctx.method_inst = inflated->context.method_inst;
guint32 pkey_len;
const char *pkey_ptr;
gchar *codebase;
- gboolean assembly_ref = FALSE;
+ MonoBoolean assembly_ref = 0;
MONO_ARCH_SAVE_REGS;
delegate = mono_object_new (mono_object_domain (type), delegate_class);
- g_assert (!method->klass->generic_container);
- /* FIXME: only do this for methods which can be shared! */
- if ((method->is_inflated && mono_method_get_context (method)->method_inst &&
- mono_class_generic_sharing_enabled (method->klass)) ||
- ((method->flags & METHOD_ATTRIBUTE_STATIC) && method->klass->generic_class)) {
- func = mono_compile_method (mono_marshal_get_static_rgctx_invoke (method));
+ 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) {
/* Creating a trampoline would leak memory */
func = mono_compile_method (method);
mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE));
}
- mono_delegate_ctor (delegate, target, func);
+ mono_delegate_ctor_with_method (delegate, target, func, method);
return delegate;
}
klass = mono_defaults.object_class;
else if (!strcmp (typename, "obj"))
klass = mono_defaults.object_class;
+ else if (!strcmp (typename, "string"))
+ klass = mono_defaults.string_class;
else if (!strcmp (typename, "bool"))
klass = mono_defaults.boolean_class;
else if (!strcmp (typename, "boolean"))
return info;
}
+/*
+ * mono_get_jit_icall_info:
+ *
+ * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
+ * caller should access it while holding the loader lock.
+ */
+GHashTable*
+mono_get_jit_icall_info (void)
+{
+ return jit_icall_hash_name;
+}
+
void
mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
{