[runtime] Add --assembly-loader=[strict,legacy] runtime argument
[mono.git] / mono / metadata / appdomain.c
index 81a92adc2e1a3ceb6b36797384d078e8770b7666..dfab9b8a7dcc3bb64ffdf4c448065b1128cfe66b 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * appdomain.c: AppDomain functions
+/**
+ * \file
+ * AppDomain functions
  *
  * Authors:
  *     Dietmar Maurer (dietmar@ximian.com)
@@ -110,6 +111,9 @@ static MonoDomain *
 mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_file, MonoError *error);
 
 
+static void
+mono_context_set_default_context (MonoDomain *domain);
+
 static char *
 get_shadow_assembly_location_base (MonoDomain *domain, MonoError *error);
 
@@ -229,14 +233,14 @@ create_domain_objects (MonoDomain *domain)
 
 /**
  * mono_runtime_init:
- * @domain: domain returned by mono_init ()
+ * \param domain domain returned by \c mono_init
  *
  * Initialize the core AppDomain: this function will run also some
  * IL initialization code, so it needs the execution engine to be fully 
  * operational.
  *
- * AppDomain.SetupInformation is set up in mono_runtime_exec_main, where
- * we know the entry_assembly.
+ * \c AppDomain.SetupInformation is set up in \c mono_runtime_exec_main, where
+ * we know the \c entry_assembly.
  *
  */
 void
@@ -298,7 +302,7 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
        /* contexts use GC handles, so they must be initialized after the GC */
        mono_context_init_checked (domain, error);
        return_if_nok (error);
-       mono_context_set (domain->default_context);
+       mono_context_set_default_context (domain);
 
 #ifndef DISABLE_SOCKETS
        mono_network_init ();
@@ -315,6 +319,15 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
        return;
 }
 
+static void
+mono_context_set_default_context (MonoDomain *domain)
+{
+       HANDLE_FUNCTION_ENTER ();
+       mono_context_set_handle (MONO_HANDLE_NEW (MonoAppContext, domain->default_context));
+       HANDLE_FUNCTION_RETURN ();
+}
+
+
 static int
 mono_get_corlib_version (void)
 {
@@ -336,11 +349,9 @@ mono_get_corlib_version (void)
 }
 
 /**
- * mono_check_corlib_version
- *
+ * mono_check_corlib_version:
  * Checks that the corlib that is loaded matches the version of this runtime.
- *
- * Returns: NULL if the runtime will work with the corlib, or a g_malloc
+ * \returns NULL if the runtime will work with the corlib, or a \c g_malloc
  * allocated string with the error otherwise.
  */
 const char*
@@ -361,9 +372,8 @@ mono_check_corlib_version (void)
 
 /**
  * mono_context_init:
- * @domain: The domain where the System.Runtime.Remoting.Context.Context is initialized
- *
- * Initializes the @domain's default System.Runtime.Remoting's Context.
+ * \param domain The domain where the \c System.Runtime.Remoting.Context.Context is initialized
+ * Initializes the \p domain's default \c System.Runtime.Remoting 's Context.
  */
 void
 mono_context_init (MonoDomain *domain)
@@ -387,13 +397,14 @@ mono_context_init_checked (MonoDomain *domain, MonoError *error)
 
        context->domain_id = domain->domain_id;
        context->context_id = 0;
-       ves_icall_System_Runtime_Remoting_Contexts_Context_RegisterContext (context);
+       mono_threads_register_app_context (context, error);
+       mono_error_assert_ok (error);
        domain->default_context = context;
 }
 
 /**
  * mono_runtime_cleanup:
- * @domain: unused.
+ * \param domain unused.
  *
  * Internal routine.
  *
@@ -422,12 +433,18 @@ mono_runtime_cleanup (MonoDomain *domain)
 
 static MonoDomainFunc quit_function = NULL;
 
+/**
+ * mono_install_runtime_cleanup:
+ */
 void
 mono_install_runtime_cleanup (MonoDomainFunc func)
 {
        quit_function = func;
 }
 
+/**
+ * mono_runtime_quit:
+ */
 void
 mono_runtime_quit ()
 {
@@ -437,10 +454,9 @@ mono_runtime_quit ()
 
 /**
  * mono_domain_create_appdomain:
- * @friendly_name: The friendly name of the appdomain to create
- * @configuration_file: The configuration file to initialize the appdomain with
- * 
- * Returns a MonoDomain initialized with the appdomain
+ * \param friendly_name The friendly name of the appdomain to create
+ * \param configuration_file The configuration file to initialize the appdomain with
+ * \returns a \c MonoDomain initialized with the appdomain
  */
 MonoDomain *
 mono_domain_create_appdomain (char *friendly_name, char *configuration_file)
@@ -454,11 +470,11 @@ mono_domain_create_appdomain (char *friendly_name, char *configuration_file)
 
 /**
  * mono_domain_create_appdomain_checked:
- * @friendly_name: The friendly name of the appdomain to create
- * @configuration_file: The configuration file to initialize the appdomain with
- * @error: Set on error.
+ * \param friendly_name The friendly name of the appdomain to create
+ * \param configuration_file The configuration file to initialize the appdomain with
+ * \param error Set on error.
  * 
- * Returns a MonoDomain initialized with the appdomain.  On failure sets @error and returns NULL.
+ * \returns a MonoDomain initialized with the appdomain.  On failure sets \p error and returns NULL.
  */
 MonoDomain *
 mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_file, MonoError *error)
@@ -492,9 +508,9 @@ leave:
 
 /**
  * mono_domain_set_config:
- * @domain: MonoDomain initialized with the appdomain we want to change
- * @base_dir: new base directory for the appdomain
- * @config_file_name: path to the new configuration for the app domain
+ * \param domain \c MonoDomain initialized with the appdomain we want to change
+ * \param base_dir new base directory for the appdomain
+ * \param config_file_name path to the new configuration for the app domain
  *
  * Used to set the system configuration for an appdomain
  *
@@ -649,10 +665,9 @@ leave:
 
 /**
  * mono_domain_has_type_resolve:
- * @domain: application domains being looked up
+ * \param domain application domain being looked up
  *
- * Returns: TRUE if the AppDomain.TypeResolve field has been
- * set.
+ * \returns TRUE if the \c AppDomain.TypeResolve field has been set.
  */
 gboolean
 mono_domain_has_type_resolve (MonoDomain *domain)
@@ -675,16 +690,16 @@ mono_domain_has_type_resolve (MonoDomain *domain)
 
 /**
  * mono_domain_try_type_resolve:
- * @domain: application domainwhere the name where the type is going to be resolved
- * @name: the name of the type to resolve or NULL.
- * @tb: A System.Reflection.Emit.TypeBuilder, used if name is NULL.
+ * \param domain application domainwhere the name where the type is going to be resolved
+ * \param name the name of the type to resolve or NULL.
+ * \param tb A \c System.Reflection.Emit.TypeBuilder, used if name is NULL.
  *
- * This routine invokes the internal System.AppDomain.DoTypeResolve and returns
+ * This routine invokes the internal \c System.AppDomain.DoTypeResolve and returns
  * the assembly that matches name.
  *
- * If @name is null, the value of ((TypeBuilder)tb).FullName is used instead
+ * If \p name is null, the value of \c ((TypeBuilder)tb).FullName is used instead
  *
- * Returns: A MonoReflectionAssembly or NULL if not found
+ * \returns A \c MonoReflectionAssembly or NULL if not found
  */
 MonoReflectionAssembly *
 mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *tb)
@@ -728,8 +743,7 @@ mono_domain_try_type_resolve_checked (MonoDomain *domain, char *name, MonoObject
 
 /**
  * mono_domain_owns_vtable_slot:
- *
- *  Returns whenever VTABLE_SLOT is inside a vtable which belongs to DOMAIN.
+ * \returns Whether \p vtable_slot is inside a vtable which belongs to \p domain.
  */
 gboolean
 mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot)
@@ -744,15 +758,13 @@ mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot)
 
 /**
  * mono_domain_set:
- * @domain: domain
- * @force: force setting.
+ * \param domain domain
+ * \param force force setting.
  *
- * Set the current appdomain to @domain. If @force is set, set it even
+ * Set the current appdomain to \p domain. If \p force is set, set it even
  * if it is being unloaded.
  *
- * Returns:
- *   TRUE on success;
- *   FALSE if the domain is unloaded
+ * \returns TRUE on success; FALSE if the domain is unloaded
  */
 gboolean
 mono_domain_set (MonoDomain *domain, gboolean force)
@@ -1828,8 +1840,10 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
        sibling_source_len = strlen (sibling_source);
        sibling_target = g_strconcat (shadow, ".config", NULL);
        sibling_target_len = strlen (sibling_target);
-       
+
        copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".mdb", sibling_target, sibling_target_len, 7);
+       if (copy_result)
+               copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".pdb", sibling_target, sibling_target_len, 11);
        if (copy_result)
                copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".config", sibling_target, sibling_target_len, 7);
        
@@ -1857,6 +1871,9 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
 }
 #endif /* DISABLE_SHADOW_COPY */
 
+/**
+ * mono_domain_from_appdomain:
+ */
 MonoDomain *
 mono_domain_from_appdomain (MonoAppDomain *appdomain_raw)
 {
@@ -1985,6 +2002,14 @@ mono_domain_assembly_preload (MonoAssemblyName *aname,
 
        set_domain_search_path (domain);
 
+       MonoAssemblyCandidatePredicate predicate = NULL;
+       void* predicate_ud = NULL;
+#if !defined(DISABLE_STRICT_STRONG_NAMES)
+       if (G_LIKELY (mono_loader_get_strict_strong_names ())) {
+               predicate = &mono_assembly_candidate_predicate_sn_same_name;
+               predicate_ud = aname;
+       }
+#endif
        if (domain->search_path && domain->search_path [0] != NULL) {
                if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY)) {
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Domain %s search path is:", domain->friendly_name);
@@ -1994,11 +2019,11 @@ mono_domain_assembly_preload (MonoAssemblyName *aname,
                        }
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "End of domain %s search path.", domain->friendly_name);                    
                }
-               result = real_load (domain->search_path, aname->culture, aname->name, refonly, &mono_assembly_candidate_predicate_sn_same_name, aname);
+               result = real_load (domain->search_path, aname->culture, aname->name, refonly, predicate, predicate_ud);
        }
 
        if (result == NULL && assemblies_path && assemblies_path [0] != NULL) {
-               result = real_load (assemblies_path, aname->culture, aname->name, refonly, &mono_assembly_candidate_predicate_sn_same_name, aname);
+               result = real_load (assemblies_path, aname->culture, aname->name, refonly, predicate, predicate_ud);
        }
 
        return result;
@@ -2206,8 +2231,9 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id, MonoError *error)
         * Unloading seems to cause problems when running NUnit/NAnt, hence
         * this workaround.
         */
-       if (g_getenv ("MONO_NO_UNLOAD"))
+       if (g_hasenv ("MONO_NO_UNLOAD"))
                return;
+
 #ifdef __native_client__
        return;
 #endif
@@ -2231,9 +2257,11 @@ ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id, Mono
 }
 
 void
-ves_icall_System_AppDomain_DoUnhandledException (MonoException *exc)
+ves_icall_System_AppDomain_DoUnhandledException (MonoExceptionHandle exc, MonoError *error)
 {
-       mono_unhandled_exception ((MonoObject*) exc);
+       error_init (error);
+       mono_unhandled_exception_checked (MONO_HANDLE_CAST (MonoObject, exc), error);
+       mono_error_assert_ok (error);
 }
 
 gint32
@@ -2331,24 +2359,27 @@ ves_icall_System_AppDomain_InternalPopDomainRef (MonoError *error)
        mono_thread_pop_appdomain_ref ();
 }
 
-MonoAppContext * 
-ves_icall_System_AppDomain_InternalGetContext ()
+MonoAppContextHandle
+ves_icall_System_AppDomain_InternalGetContext (MonoError *error)
 {
-       return mono_context_get ();
+       error_init (error);
+       return mono_context_get_handle ();
 }
 
-MonoAppContext * 
-ves_icall_System_AppDomain_InternalGetDefaultContext ()
+MonoAppContextHandle
+ves_icall_System_AppDomain_InternalGetDefaultContext (MonoError *error)
 {
-       return mono_domain_get ()->default_context;
+       error_init (error);
+       return MONO_HANDLE_NEW (MonoAppContext, mono_domain_get ()->default_context);
 }
 
-MonoAppContext * 
-ves_icall_System_AppDomain_InternalSetContext (MonoAppContext *mc)
+MonoAppContextHandle
+ves_icall_System_AppDomain_InternalSetContext (MonoAppContextHandle mc, MonoError *error)
 {
-       MonoAppContext *old_context = mono_context_get ();
+       error_init (error);
+       MonoAppContextHandle old_context = mono_context_get_handle ();
 
-       mono_context_set (mc);
+       mono_context_set_handle (mc);
 
        return old_context;
 }
@@ -2371,6 +2402,9 @@ ves_icall_System_AppDomain_InternalGetProcessGuid (MonoStringHandle newguid, Mon
        return newguid;
 }
 
+/**
+ * mono_domain_is_unloading:
+ */
 gboolean
 mono_domain_is_unloading (MonoDomain *domain)
 {
@@ -2560,12 +2594,12 @@ failure:
        return 1;
 }
 
-/*
+/**
  * mono_domain_unload:
- * @domain: The domain to unload
+ * \param domain The domain to unload
  *
- *  Unloads an appdomain. Follows the process outlined in the comment
- *  for mono_domain_try_unload.
+ * Unloads an appdomain. Follows the process outlined in the comment
+ * for \c mono_domain_try_unload.
  */
 void
 mono_domain_unload (MonoDomain *domain)
@@ -2586,10 +2620,10 @@ guarded_wait (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertab
        return result;
 }
 
-/*
+/**
  * mono_domain_unload:
- * @domain: The domain to unload
- * @exc: Exception information
+ * \param domain The domain to unload
+ * \param exc Exception information
  *
  *  Unloads an appdomain. Follows the process outlined in:
  *  http://blogs.gotdotnet.com/cbrumme