#include <mono/metadata/object.h>
#include <mono/metadata/threads.h>
+#include <mono/metadata/threads-types.h>
#include <mono/metadata/threadpool.h>
#include <mono/metadata/monitor.h>
#include <mono/metadata/reflection.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/tokentype.h>
#include <mono/metadata/unicode.h>
-#include <mono/metadata/appdomain.h>
+#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/metadata-internals.h>
+#include <mono/metadata/class-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/rand.h>
return FALSE;
}
+static void
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
+ MonoReflectionType *t)
+{
+ enumtype->type = t->type;
+}
+
static MonoReflectionType*
ves_icall_MonoGenericInst_GetParentType (MonoReflectionGenericInst *type)
{
*/
MonoMethod *m = method->method;
int pcount;
+ void *obj = this;
MONO_ARCH_SAVE_REGS;
if (!mono_object_isinst (this, m->klass))
mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
m = mono_object_get_virtual_method (this, m);
+ /* must pass the pointer to the value for valuetype methods */
+ if (m->klass->valuetype)
+ obj = mono_object_unbox (this);
} else if (!(m->flags & METHOD_ATTRIBUTE_STATIC) && strcmp (m->name, ".ctor") && !m->wrapper_type)
mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
}
- return mono_runtime_invoke_array (m, this, params, NULL);
+ return mono_runtime_invoke_array (m, obj, params, NULL);
}
static MonoObject *
str = mono_string_to_utf8 (name);
- for (i = 0; i < k->field.count; i++) {
- if (!strcmp (k->fields [i].name, str)) {
- MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
- if (field_klass->valuetype)
- result = mono_value_box (domain, field_klass,
- (char *)this + k->fields [i].offset);
- else
- result = *((gpointer *)((char *)this + k->fields [i].offset));
-
- g_assert (result);
- out_args = mono_array_new (domain, mono_defaults.object_class, 1);
- *outArgs = out_args;
- mono_array_set (out_args, gpointer, 0, result);
- g_free (str);
- return NULL;
+ do {
+ for (i = 0; i < k->field.count; i++) {
+ if (!strcmp (k->fields [i].name, str)) {
+ MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
+ if (field_klass->valuetype)
+ result = mono_value_box (domain, field_klass,
+ (char *)this + k->fields [i].offset);
+ else
+ result = *((gpointer *)((char *)this + k->fields [i].offset));
+
+ g_assert (result);
+ out_args = mono_array_new (domain, mono_defaults.object_class, 1);
+ *outArgs = out_args;
+ mono_array_set (out_args, gpointer, 0, result);
+ g_free (str);
+ return NULL;
+ }
}
- }
+ k = k->parent;
+ }
+ while (k != NULL);
g_free (str);
g_assert_not_reached ();
str = mono_string_to_utf8 (name);
- for (i = 0; i < k->field.count; i++) {
- if (!strcmp (k->fields [i].name, str)) {
- MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
- MonoObject *val = mono_array_get (params, gpointer, 2);
-
- if (field_klass->valuetype) {
- size = mono_type_size (k->fields [i].type, &align);
- memcpy ((char *)this + k->fields [i].offset,
- ((char *)val) + sizeof (MonoObject), size);
- } else
- *(MonoObject**)((char *)this + k->fields [i].offset) = val;
-
- out_args = mono_array_new (domain, mono_defaults.object_class, 0);
- *outArgs = out_args;
-
- g_free (str);
- return NULL;
+ do {
+ for (i = 0; i < k->field.count; i++) {
+ if (!strcmp (k->fields [i].name, str)) {
+ MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
+ MonoObject *val = mono_array_get (params, gpointer, 2);
+
+ if (field_klass->valuetype) {
+ size = mono_type_size (k->fields [i].type, &align);
+ memcpy ((char *)this + k->fields [i].offset,
+ ((char *)val) + sizeof (MonoObject), size);
+ } else
+ *(MonoObject**)((char *)this + k->fields [i].offset) = val;
+
+ out_args = mono_array_new (domain, mono_defaults.object_class, 0);
+ *outArgs = out_args;
+
+ g_free (str);
+ return NULL;
+ }
}
- }
+ k = k->parent;
+ }
+ while (k != NULL);
g_free (str);
g_assert_not_reached ();
if (!strcmp (method->method->name, ".ctor"))
g_assert_not_reached ();
+ /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
+ g_assert (!method->method->klass->valuetype);
result = mono_runtime_invoke_array (method->method, this, params, NULL);
for (i = 0, j = 0; i < mono_array_length (params); i++) {
if (mono_field_is_deleted (field))
continue;
mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
- if (!field->def_value) {
- field->def_value = g_new0 (MonoConstant, 1);
+
+ if (!field->data) {
crow = mono_metadata_get_constant_index (enumc->image, MONO_TOKEN_FIELD_DEF | (i+enumc->field.first+1), crow + 1);
- field->def_value->type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
+ field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
- field->def_value->value = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
+ field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
}
- p = field->def_value->value;
+ p = field->data;
len = mono_metadata_decode_blob_size (p, &p);
switch (enumc->enum_basetype->type) {
case MONO_TYPE_U1:
MonoAssembly **ptr;
MonoDomain *domain = mono_object_domain (assembly);
int i, count = 0;
+ static MonoMethod *create_culture = NULL;
MONO_ARCH_SAVE_REGS;
for (ptr = assembly->assembly->image->references; ptr && *ptr; ptr++)
count++;
- result = mono_array_new (mono_object_domain (assembly), System_Reflection_AssemblyName, count);
+ result = mono_array_new (domain, System_Reflection_AssemblyName, count);
+
+ if (count > 0) {
+ MonoMethodDesc *desc = mono_method_desc_new (
+ "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
+ create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
+ g_assert (create_culture);
+ mono_method_desc_free (desc);
+ }
for (i = 0; i < count; i++) {
MonoAssembly *assem = assembly->assembly->image->references [i];
aname->minor = assem->aname.minor;
aname->build = assem->aname.build;
aname->revision = assem->aname.revision;
+ aname->revision = assem->aname.revision;
+ aname->hashalg = assem->aname.hash_alg;
+ aname->flags = assem->aname.flags;
+
+ if (create_culture) {
+ gpointer args [1];
+ args [0] = mono_string_new (domain, assem->aname.culture);
+ aname->cultureInfo = mono_runtime_invoke (create_culture, NULL, args, NULL);
+ }
+
+ if (assem->aname.public_key) {
+ guint32 pkey_len;
+ const char *pkey_ptr = assem->aname.public_key;
+ pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
+
+ aname->publicKey = mono_array_new (domain, mono_defaults.byte_class, pkey_len);
+ memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
+ }
+
+ /* public key token isn't copied - the class library will
+ automatically generate it from the public key if required */
absolute = g_build_filename (assem->basedir, assem->image->module_name, NULL);
codebase = g_filename_to_uri (absolute, NULL, NULL);
* this code should only be called after obtaining the
* ResourceInfo and handling the other cases.
*/
- g_assert ((impl & IMPLEMENTATION_MASK) == IMPLEMENTATION_FILE);
- file_idx = impl >> IMPLEMENTATION_BITS;
+ g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
+ file_idx = impl >> MONO_IMPLEMENTATION_BITS;
module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
if (!module)
info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
}
else {
- switch (cols [MONO_MANIFEST_IMPLEMENTATION] & IMPLEMENTATION_MASK) {
- case IMPLEMENTATION_FILE:
- i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
+ switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
+ case MONO_IMPLEMENTATION_FILE:
+ i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
info->location = RESOURCE_LOCATION_EMBEDDED;
break;
- case IMPLEMENTATION_ASSEMBLYREF:
- i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
+ case MONO_IMPLEMENTATION_ASSEMBLYREF:
+ i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
info->assembly = mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]);
/* Obtain info recursively */
info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
break;
- case IMPLEMENTATION_EXP_TYPE:
+ case MONO_IMPLEMENTATION_EXP_TYPE:
g_assert_not_reached ();
break;
}
MONO_ARCH_SAVE_REGS;
if (!domain->entry_assembly)
- domain = mono_root_domain;
+ domain = mono_get_root_domain ();
return mono_assembly_get_object (domain, domain->entry_assembly);
}
t1 += 60;
tt1 = *localtime (&t1);
} while (gmt_offset (&tt1, t1) == gmtoff);
-
+ t1+=gmtoff;
strftime (tzone, sizeof (tzone), "%Z", &tt);
/* Write data, if we're already in daylight saving, we're done. */
MONO_ARCH_SAVE_REGS;
- path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", "machine.config", NULL);
+ path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_framework_version (), "machine.config", NULL);
#if defined (PLATFORM_WIN32)
/* Avoid mixing '/' and '\\' */
iter->args = (char*)iter->args + arg_size;
iter->next_arg++;
- //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
+ /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
return res;
}
arg_size = mono_type_stack_size (res.type, &align);
iter->args = (char*)iter->args + arg_size;
iter->next_arg++;
- //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
+ /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
return res;
}
- //g_print ("arg type 0x%02x not found\n", res.type->type);
+ /* g_print ("arg type 0x%02x not found\n", res.type->type); */
res.type = NULL;
res.value = NULL;
{"SetData", ves_icall_System_AppDomain_SetData},
{"createDomain", ves_icall_System_AppDomain_createDomain},
{"getCurDomain", ves_icall_System_AppDomain_getCurDomain},
+ {"getDomainByID", ves_icall_System_AppDomain_getDomainByID},
{"getFriendlyName", ves_icall_System_AppDomain_getFriendlyName},
{"getSetup", ves_icall_System_AppDomain_getSetup}
};
{"setup_internal_class", mono_reflection_setup_internal_class}
};
+static const IcallEntry enumbuilder_icalls [] = {
+ {"setup_enum_type", ves_icall_EnumBuilder_setup_enum_type}
+};
+
static const IcallEntry runtimehelpers_icalls [] = {
{"GetObjectValue", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue},
+ /* REMOVEME: no longer needed, just so we dont break things when not needed */
{"GetOffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData},
{"InitializeArray", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray},
- {"RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor}
+ {"RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor},
+ {"get_OffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData}
};
static const IcallEntry gchandle_icalls [] = {
};
static const IcallEntry mutex_icalls [] = {
- {"CreateMutex_internal", ves_icall_System_Threading_Mutex_CreateMutex_internal},
- {"ReleaseMutex_internal", ves_icall_System_Threading_Mutex_ReleaseMutex_internal}
+ {"CreateMutex_internal(bool,string,bool&)", ves_icall_System_Threading_Mutex_CreateMutex_internal},
+ {"ReleaseMutex_internal(intptr)", ves_icall_System_Threading_Mutex_ReleaseMutex_internal}
};
static const IcallEntry nativeevents_icalls [] = {
{"System.Reflection.Emit.AssemblyBuilder", assemblybuilder_icalls, G_N_ELEMENTS (assemblybuilder_icalls)},
{"System.Reflection.Emit.CustomAttributeBuilder", customattrbuilder_icalls, G_N_ELEMENTS (customattrbuilder_icalls)},
{"System.Reflection.Emit.DynamicMethod", dynamicmethod_icalls, G_N_ELEMENTS (dynamicmethod_icalls)},
+ {"System.Reflection.Emit.EnumBuilder", enumbuilder_icalls, G_N_ELEMENTS (enumbuilder_icalls)},
{"System.Reflection.Emit.GenericTypeParameterBuilder", generictypeparambuilder_icalls, G_N_ELEMENTS (generictypeparambuilder_icalls)},
{"System.Reflection.Emit.MethodBuilder", methodbuilder_icalls, G_N_ELEMENTS (methodbuilder_icalls)},
{"System.Reflection.Emit.ModuleBuilder", modulebuilder_icalls, G_N_ELEMENTS (modulebuilder_icalls)},
};
static GHashTable *icall_hash = NULL;
+static GHashTable *jit_icall_hash_name = NULL;
+static GHashTable *jit_icall_hash_addr = NULL;
void
mono_init_icall (void)
return NULL;
}
+static MonoType*
+type_from_typename (char *typename)
+{
+ MonoClass *klass;
+
+ if (!strcmp (typename, "int"))
+ klass = mono_defaults.int_class;
+ else if (!strcmp (typename, "ptr"))
+ klass = mono_defaults.int_class;
+ else if (!strcmp (typename, "void"))
+ klass = mono_defaults.void_class;
+ else if (!strcmp (typename, "int32"))
+ klass = mono_defaults.int32_class;
+ else if (!strcmp (typename, "uint32"))
+ klass = mono_defaults.uint32_class;
+ else if (!strcmp (typename, "long"))
+ klass = mono_defaults.int64_class;
+ else if (!strcmp (typename, "ulong"))
+ klass = mono_defaults.uint64_class;
+ else if (!strcmp (typename, "float"))
+ klass = mono_defaults.single_class;
+ else if (!strcmp (typename, "double"))
+ klass = mono_defaults.double_class;
+ else if (!strcmp (typename, "object"))
+ klass = mono_defaults.object_class;
+ else if (!strcmp (typename, "obj"))
+ klass = mono_defaults.object_class;
+ else {
+ g_error (typename);
+ g_assert_not_reached ();
+ }
+ return &klass->byval_arg;
+}
+
+MonoMethodSignature*
+mono_create_icall_signature (const char *sigstr)
+{
+ gchar **parts;
+ int i, len;
+ gchar **tmp;
+ MonoMethodSignature *res;
+
+ mono_loader_lock ();
+ res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
+ if (res) {
+ mono_loader_unlock ();
+ return res;
+ }
+
+ parts = g_strsplit (sigstr, " ", 256);
+
+ tmp = parts;
+ len = 0;
+ while (*tmp) {
+ len ++;
+ tmp ++;
+ }
+
+ res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
+ res->pinvoke = 1;
+
+#ifdef PLATFORM_WIN32
+ /*
+ * Under windows, the default pinvoke calling convention is STDCALL but
+ * we need CDECL.
+ */
+ res->call_convention = MONO_CALL_C;
+#endif
+
+ res->ret = type_from_typename (parts [0]);
+ for (i = 1; i < len; ++i) {
+ res->params [i - 1] = type_from_typename (parts [i]);
+ }
+
+ g_strfreev (parts);
+
+ g_hash_table_insert (mono_defaults.corlib->helper_signatures, sigstr, res);
+
+ mono_loader_unlock ();
+
+ return res;
+}
+
+MonoJitICallInfo *
+mono_find_jit_icall_by_name (const char *name)
+{
+ MonoJitICallInfo *info;
+ g_assert (jit_icall_hash_name);
+
+ mono_loader_lock ();
+ info = g_hash_table_lookup (jit_icall_hash_name, name);
+ mono_loader_unlock ();
+ return info;
+}
+
+MonoJitICallInfo *
+mono_find_jit_icall_by_addr (gconstpointer addr)
+{
+ MonoJitICallInfo *info;
+ g_assert (jit_icall_hash_addr);
+
+ mono_loader_lock ();
+ info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
+ mono_loader_unlock ();
+
+ return info;
+}
+
+void
+mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
+{
+ mono_loader_lock ();
+ g_hash_table_insert (jit_icall_hash_addr, (gpointer)info->wrapper, info);
+ mono_loader_unlock ();
+}
+
+MonoJitICallInfo *
+mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
+{
+ MonoJitICallInfo *info;
+
+ g_assert (func);
+ g_assert (name);
+
+ mono_loader_lock ();
+
+ if (!jit_icall_hash_name) {
+ jit_icall_hash_name = g_hash_table_new (g_str_hash, g_str_equal);
+ jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
+ }
+
+ if (g_hash_table_lookup (jit_icall_hash_name, name)) {
+ g_warning ("jit icall already defined \"%s\"\n", name);
+ g_assert_not_reached ();
+ }
+
+ info = g_new (MonoJitICallInfo, 1);
+
+ info->name = name;
+ info->func = func;
+ info->sig = sig;
+
+ if (is_save) {
+ info->wrapper = func;
+ } else {
+ info->wrapper = NULL;
+ }
+
+ g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
+ g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
+
+ mono_loader_unlock ();
+ return info;
+}