#include <glib.h>
#include <string.h>
+#if HAVE_BOEHM_GC
+#include <gc/gc.h>
+#endif
+
#include <mono/metadata/object.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/assembly.h>
static guint32 appdomain_thread_id = 0;
+static MonoJitInfoTable *
+mono_jit_info_table_new ()
+{
+ return g_array_new (FALSE, FALSE, sizeof (gpointer));
+}
+
+static void
+mono_jit_info_table_free (MonoJitInfoTable *table)
+{
+ g_array_free (table, TRUE);
+}
+
+static int
+mono_jit_info_table_index (MonoJitInfoTable *table, gpointer addr)
+{
+ int left = 0, right = table->len;
+
+ while (left < right) {
+ int pos = (left + right) / 2;
+ MonoJitInfo *ji = g_array_index (table, gpointer, pos);
+ gpointer start = ji->code_start;
+ gpointer end = start + ji->code_size;
+
+ if (addr < start)
+ right = pos;
+ else if (addr >= end)
+ left = pos + 1;
+ else
+ return pos;
+ }
+
+ return left;
+}
+
+MonoJitInfo *
+mono_jit_info_table_find (MonoDomain *domain, gpointer addr)
+{
+ MonoJitInfoTable *table = domain->jit_info_table;
+ int left = 0, right = table->len;
+
+ while (left < right) {
+ int pos = (left + right) / 2;
+ MonoJitInfo *ji = g_array_index (table, gpointer, pos);
+ gpointer start = ji->code_start;
+ gpointer end = start + ji->code_size;
+
+ if (addr < start)
+ right = pos;
+ else if (addr >= end)
+ left = pos + 1;
+ else
+ return ji;
+ }
+
+ /* maybe irt is shared code, so we also search in the root domain */
+ if (domain != mono_root_domain)
+ return mono_jit_info_table_find (domain, addr);
+
+ return NULL;
+}
+
+void
+mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji)
+{
+ MonoJitInfoTable *table = domain->jit_info_table;
+ gpointer start = ji->code_start;
+ int pos = mono_jit_info_table_index (table, start);
+
+ g_array_insert_val (table, pos, ji);
+}
+
static int
ldstr_hash (const char* str)
{
return memcmp (str1, str2, len) == 0;
}
+#if HAVE_BOEHM_GC
+static void
+domain_finalizer (void *obj, void *data) {
+ g_print ("domain finalized\n");
+}
+#endif
+
static MonoDomain *
mono_create_domain ()
{
MonoDomain *domain;
+#if HAVE_BOEHM_GC
+ domain = GC_malloc (sizeof (MonoDomain));
+ GC_register_finalizer (domain, domain_finalizer, NULL, NULL, NULL);
+#else
domain = g_new0 (MonoDomain, 1);
+#endif
domain->domain = NULL;
domain->setup = NULL;
domain->friendly_name = NULL;
+ domain->mp = mono_mempool_new ();
domain->env = g_hash_table_new (g_str_hash, g_str_equal);
domain->assemblies = g_hash_table_new (g_str_hash, g_str_equal);
- domain->class_vtable_hash = g_hash_table_new (NULL, NULL);
+ domain->class_vtable_hash = mono_g_hash_table_new (NULL, NULL);
domain->jit_code_hash = g_hash_table_new (NULL, NULL);
- domain->ldstr_table = g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
-
+ domain->ldstr_table = mono_g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
+ domain->jit_info_table = mono_jit_info_table_new ();
return domain;
}
+MonoDomain *mono_root_domain = NULL;
+
/**
* mono_init:
*
* Returns: the initial domain.
*/
MonoDomain *
-mono_init ()
+mono_init (const char *filename)
{
static MonoDomain *domain = NULL;
MonoAppDomainSetup *setup;
appdomain_thread_id = TlsAlloc ();
domain = mono_create_domain ();
+ mono_root_domain = domain;
TlsSetValue (appdomain_thread_id, domain);
/* find the corlib */
ass = mono_assembly_open (CORLIB_NAME, NULL, &status);
- g_assert (status == MONO_IMAGE_OK);
- g_assert (ass != NULL);
+ if ((status != MONO_IMAGE_OK) || (ass == NULL)) {
+ switch (status){
+ case MONO_IMAGE_ERROR_ERRNO:
+ g_print ("The assembly corlib.dll was not found or could not be loaded.\n");
+ g_print ("It should have been installed in the `%s' directory.\n", MONO_ASSEMBLIES);
+ break;
+ case MONO_IMAGE_IMAGE_INVALID:
+ g_print ("The file %s/corlib.dll is an invalid CIL image\n", MONO_ASSEMBLIES);
+ break;
+ case MONO_IMAGE_MISSING_ASSEMBLYREF:
+ g_print ("Minning assembly reference in %s/corlib.dll\n", MONO_ASSEMBLIES);
+ break;
+ case MONO_IMAGE_OK:
+ /* to suppress compiler warning */
+ }
+
+ exit (1);
+ }
mono_defaults.corlib = ass->image;
mono_defaults.object_class = mono_class_from_name (
mono_defaults.corlib, "System", "Array");
g_assert (mono_defaults.array_class != 0);
- mono_defaults.delegate_class = mono_class_from_name (
- mono_defaults.corlib, "System", "Delegate");
- g_assert (mono_defaults.delegate_class != 0);
+ mono_defaults.multicastdelegate_class = mono_class_from_name (
+ mono_defaults.corlib, "System", "MulticastDelegate");
+ g_assert (mono_defaults.multicastdelegate_class != 0 );
+
+ mono_defaults.asyncresult_class = mono_class_from_name (
+ mono_defaults.corlib, "System.Runtime.Remoting.Messaging",
+ "AsyncResult");
+ g_assert (mono_defaults.asyncresult_class != 0 );
+
+ mono_defaults.waithandle_class = mono_class_from_name (
+ mono_defaults.corlib, "System.Threading", "WaitHandle");
+ g_assert (mono_defaults.waithandle_class != 0 );
mono_defaults.typehandle_class = mono_class_from_name (
mono_defaults.corlib, "System", "RuntimeTypeHandle");
mono_defaults.corlib, "System", "Exception");
g_assert (mono_defaults.exception_class != 0);
+ mono_defaults.thread_class = mono_class_from_name (
+ mono_defaults.corlib, "System.Threading", "Thread");
+ g_assert (mono_defaults.thread_class != 0);
class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
setup = (MonoAppDomainSetup *) mono_object_new (domain, class);
ves_icall_System_AppDomainSetup_InitAppDomainSetup (setup);
- name = mono_string_new (domain, "Default Domain");
+ name = mono_string_new (domain, g_path_get_basename (filename));
class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
ad = (MonoAppDomain *) mono_object_new (domain, class);
static MonoObject *
mono_domain_transfer_object (MonoDomain *src, MonoDomain *dst, MonoObject *obj)
{
+ MonoClass *klass;
+ MonoObject *res;
+
+ if (!obj)
+ return NULL;
+
+ g_assert (obj->vtable->domain == src);
+
/* fixme: transfer an object from one domain into another */
- g_assert_not_reached ();
- return obj;
+
+ klass = obj->vtable->klass;
+
+ if (MONO_CLASS_IS_ARRAY (klass)) {
+ MonoArray *ao = (MonoArray *)obj;
+ int esize, ecount, i;
+ guint32 *sizes;
+
+ sizes = alloca (klass->rank * sizeof(guint32) * 2);
+ esize = mono_array_element_size (klass);
+ ecount = 1;
+ for (i = 0; i < klass->rank; ++i) {
+ sizes [i] = ao->bounds [i].length;
+ ecount *= ao->bounds [i].length;
+ sizes [i + klass->rank] = ao->bounds [i].lower_bound;
+ }
+ res = (MonoObject *)mono_array_new_full (dst, klass, sizes, sizes + klass->rank);
+ if (klass->element_class->valuetype) {
+ memcpy (res, (char *)ao + sizeof(MonoArray), esize * ecount);
+ } else {
+ g_assert (esize == sizeof (gpointer));
+ for (i = 0; i < ecount; i++) {
+ int offset = sizeof (MonoArray) + esize * i;
+ gpointer *src_ea = (gpointer *)((char *)ao + offset);
+ gpointer *dst_ea = (gpointer *)((char *)res + offset);
+
+ *dst_ea = mono_domain_transfer_object (src, dst, *src_ea);
+ }
+ }
+ } else if (klass == mono_defaults.string_class) {
+ MonoString *str = (MonoString *)obj;
+ res = (MonoObject *)mono_string_new_utf16 (dst,
+ (const guint16 *)str->c_str->vector, str->length);
+ } else {
+ // fixme: we need generic marshalling code here */
+ g_assert_not_reached ();
+ }
+
+ return res;
}
MonoObject *
void
ves_icall_System_AppDomain_Unload (MonoAppDomain *ad)
{
- mono_domain_unload (ad->data);
+ mono_domain_unload (ad->data, FALSE);
}
/**
return ass;
}
+static void
+remove_assembly (gpointer key, gpointer value, gpointer user_data)
+{
+ mono_assembly_close ((MonoAssembly *)value);
+}
+
void
-mono_domain_unload (MonoDomain *domain)
+mono_domain_unload (MonoDomain *domain, gboolean force)
{
- g_warning ("Domain unloading not yet implemented");
+ if ((domain == mono_root_domain) && !force) {
+ g_warning ("cant unload root domain");
+ return;
+ }
+
+ g_hash_table_foreach (domain->assemblies, remove_assembly, NULL);
+
+ g_hash_table_destroy (domain->env);
+ g_hash_table_destroy (domain->assemblies);
+ mono_g_hash_table_destroy (domain->class_vtable_hash);
+ g_hash_table_destroy (domain->jit_code_hash);
+ mono_g_hash_table_destroy (domain->ldstr_table);
+ mono_jit_info_table_free (domain->jit_info_table);
+ mono_mempool_destroy (domain->mp);
+
+ // fixme: anything else required ? */
+
+#if HAVE_BOEHM_GC
+#else
+ g_free (domain);
+#endif
+
+ if ((domain == mono_root_domain))
+ mono_root_domain = NULL;
}
gint32
MonoImage *image;
MonoCLIImageInfo *iinfo;
MonoMethod *method;
+ MonoObject *margs;
char *filename;
gint32 res;
if (!method)
g_error ("No entry point method found in %s", image->name);
- res = mono_runtime_exec_main (method, args);
+ margs = mono_domain_transfer_object (cdom, ad->data, (MonoObject *)args);
+ res = mono_runtime_exec_main (method, (MonoArray *)margs);
mono_domain_set (cdom);
return res;
}
+