2003-04-24 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / appdomain.c
index a0f3e015493bf796137959ac281df47923a849d4..4a7f1104c2d4d788bc13e32bbc716996a31d74fd 100644 (file)
@@ -1,11 +1,12 @@
 /*
  * appdomain.c: AppDomain functions
  *
- * Author:
+ * Authors:
  *     Dietmar Maurer (dietmar@ximian.com)
  *     Patrik Torstensson
+ *     Gonzalo Paniagua Javier (gonzalo@ximian.com)
  *
- * (C) 2001 Ximian, Inc.
+ * (c) 2001-2003 Ximian, Inc. (http://www.ximian.com)
  */
 
 #include <config.h>
@@ -26,6 +27,9 @@
 HANDLE mono_delegate_semaphore = NULL;
 CRITICAL_SECTION mono_delegate_section;
 
+static gunichar2 process_guid [36];
+static gboolean process_guid_set = FALSE;
+
 static MonoAssembly *
 mono_domain_assembly_preload (MonoAssemblyName *aname,
                              gchar **assemblies_path,
@@ -34,6 +38,9 @@ mono_domain_assembly_preload (MonoAssemblyName *aname,
 static void
 mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data);
 
+static MonoMethod *
+look_for_method_by_name (MonoClass *klass, const gchar *name);
+
 /*
  * mono_runtime_init:
  * @domain: domain returned by mono_init ()
@@ -71,6 +78,9 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        g_assert (mono_delegate_semaphore != INVALID_HANDLE_VALUE);
        InitializeCriticalSection (&mono_delegate_section);
 
+       mono_context_init (domain);
+       mono_context_set (domain->default_context);
+
        mono_thread_init (start_cb, attach_cb);
        
        /* GC init has to happen after thread init */
@@ -81,6 +91,19 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        return;
 }
 
+void
+mono_context_init (MonoDomain *domain)
+{
+       MonoClass *class;
+       MonoAppContext *context;
+
+       class = mono_class_from_name (mono_defaults.corlib, "System.Runtime.Remoting.Contexts", "Context");
+       context = (MonoAppContext *) mono_object_new (domain, class);
+       context->domain_id = domain->domain_id;
+       context->context_id = 0;
+       domain->default_context = context;
+}
+
 /* This must not be called while there are still running threads executing
  * managed code.
  */
@@ -93,14 +116,34 @@ mono_runtime_cleanup (MonoDomain *domain)
        mono_network_cleanup ();
 }
 
+gboolean
+mono_domain_has_type_resolve (MonoDomain *domain)
+{
+       static MonoClassField *field = NULL;
+       MonoObject *o;
+
+       if (field == NULL) {
+               MonoClass *klass = mono_defaults.appdomain_class;
+               int i;
+
+               for (i = 0; i < klass->field.count; ++i)
+                       if (strcmp (klass->fields [i].name, "TypeResolve") == 0)
+                               field = &klass->fields [i];
+               g_assert (field);
+       }
+
+       mono_field_get_value ((MonoObject*)(domain->domain), field, &o);
+       return o != NULL;
+}
+
 MonoReflectionAssembly *
-mono_domain_try_type_resolve (MonoDomain *domain, MonoObject *name_or_tb)
+mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *tb)
 {
        MonoClass *klass;
        void *params [1];
        static MonoMethod *method = NULL;
 
-       g_assert (domain != NULL && name_or_tb != NULL);
+       g_assert (domain != NULL && ((name != NULL) || (tb != NULL)));
 
        if (method == NULL) {
                klass = domain->domain->mbr.obj.vtable->klass;
@@ -113,7 +156,10 @@ mono_domain_try_type_resolve (MonoDomain *domain, MonoObject *name_or_tb)
                }
        }
 
-       *params = name_or_tb;
+       if (name)
+               *params = (MonoObject*)mono_string_new (mono_domain_get (), name);
+       else
+               *params = tb;
        return (MonoReflectionAssembly *) mono_runtime_invoke (method, domain->domain, params, NULL);
 }
 
@@ -237,7 +283,7 @@ ves_icall_System_AppDomain_getCurDomain ()
 MonoAppDomain *
 ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
 {
-       MonoDomain *domain = mono_domain_get (); 
+       /*MonoDomain *domain = mono_domain_get (); */
        MonoClass *adclass;
        MonoAppDomain *ad;
        MonoDomain *data;
@@ -255,6 +301,8 @@ ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomai
        data->setup = setup;
        data->friendly_name = mono_string_to_utf8 (friendly_name);
 
+       mono_context_init (data);
+
        /* FIXME: what to do next ? */
 
        return ad;
@@ -393,6 +441,7 @@ set_domain_search_path (MonoDomain *domain)
        gint i;
        gint npaths = 0;
        gchar **pvt_split = NULL;
+       GError *error = NULL;
 
        if (domain->search_path != NULL)
                return;
@@ -428,8 +477,22 @@ set_domain_search_path (MonoDomain *domain)
                /* FIXME: is this needed? */
                if (strncmp (*tmp, "file://", 7) == 0) {
                        gchar *file = *tmp;
-                       *tmp = g_strdup (*tmp + 7);
-                       g_free (file);
+                       gchar *uri = *tmp;
+
+                       if (uri [7] != '/')
+                               uri = g_strdup_printf ("file:///%s", uri + 7);
+
+                       *tmp = g_filename_from_uri (uri, NULL, &error);
+                       if (uri != file)
+                               g_free (uri);
+
+                       if (error != NULL) {
+                               g_warning ("%s\n", error->message);
+                               g_error_free (error);
+                               *tmp = file;
+                       } else {
+                               g_free (file);
+                       }
                }
                
        } else {
@@ -548,10 +611,6 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname)
                
        name = filename = mono_string_to_utf8 (fname);
 
-       /* FIXME: move uri handling to mono_assembly_open */
-       if (strncmp (filename, "file://", 7) == 0)
-               filename += 7;
-
        ass = mono_assembly_open (filename, &status);
        
        g_free (name);
@@ -656,6 +715,7 @@ get_info_from_assembly_name (MonoReflectionAssemblyName *assRef, MonoAssemblyNam
                value = g_strstrip (g_strdup (value));
                len = strlen (value);
                if (len % 2) {
+                       g_free (value);
                        g_strfreev (parts);
                        return FALSE;
                }
@@ -668,6 +728,7 @@ get_info_from_assembly_name (MonoReflectionAssemblyName *assRef, MonoAssemblyNam
                        if (i % 2) {
                                l = g_ascii_xdigit_value (value [i]);
                                if (l == -1) {
+                                       g_free (value);
                                        g_strfreev (parts);
                                        return FALSE;
                                }
@@ -675,11 +736,13 @@ get_info_from_assembly_name (MonoReflectionAssemblyName *assRef, MonoAssemblyNam
                        } else {
                                h = g_ascii_xdigit_value (value [i]);
                                if (h == -1) {
+                                       g_free (value);
                                        g_strfreev (parts);
                                        return FALSE;
                                }
                        }
                }
+               g_free (value);
 
                /*
                g_print ("PublicKeyToken: ");
@@ -739,9 +802,10 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoReflectionAssem
 void
 ves_icall_System_AppDomain_InternalUnload (gint32 domain_id)
 {
+       MonoDomain * domain = mono_domain_get_by_id (domain_id);
+
        MONO_ARCH_SAVE_REGS;
 
-       MonoDomain * domain = mono_domain_get_by_id (domain_id);
        if (NULL == domain) {
                MonoException *exc = mono_get_exception_execution_engine ("Failed to unload domain, domain id not found");
                mono_raise_exception (exc);
@@ -780,7 +844,7 @@ ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad, MonoString *file,
                g_error ("No entry point method found in %s", image->name);
 
        if (!args)
-               args = (MonoObject *) mono_array_new (ad->data, mono_defaults.string_class, 0);
+               args = (MonoArray *) mono_array_new (ad->data, mono_defaults.string_class, 0);
 
        res = mono_runtime_exec_main (method, (MonoArray *)args, NULL);
 
@@ -828,16 +892,36 @@ ves_icall_System_AppDomain_InternalGetContext ()
        return mono_context_get ();
 }
 
+MonoAppContext * 
+ves_icall_System_AppDomain_InternalGetDefaultContext ()
+{
+       MONO_ARCH_SAVE_REGS;
+
+       return mono_domain_get ()->default_context;
+}
+
 MonoAppContext * 
 ves_icall_System_AppDomain_InternalSetContext (MonoAppContext *mc)
 {
        MonoAppContext *old_context = mono_context_get ();
-       MonoDomain *context_domain = mono_domain_get_by_id (mc->domain_id);
 
        MONO_ARCH_SAVE_REGS;
 
        mono_context_set (mc);
-       mono_domain_set (context_domain);
        
        return old_context;
 }
+
+MonoString *
+ves_icall_System_AppDomain_InternalGetProcessGuid (MonoString* newguid)
+{
+       mono_domain_lock (mono_root_domain);
+       if (process_guid_set) {
+               mono_domain_unlock (mono_root_domain);
+               return mono_string_new_utf16 (mono_domain_get (), process_guid, sizeof(process_guid)/2);
+       }
+       memcpy (process_guid, mono_string_chars(newguid), sizeof(process_guid));
+       process_guid_set = TRUE;
+       mono_domain_unlock (mono_root_domain);
+       return newguid;
+}