Merge System/MonoType.cs into ReferenceSources/RuntimeType.cs, use th… (#3045)
[mono.git] / mono / metadata / appdomain.c
index d618bef480307dc0ebc45309dc886a1bc2f82184..7d5efc30c109ccb33e29840b6e0489675f9a2c88 100644 (file)
@@ -9,6 +9,7 @@
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  * Copyright 2012 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #undef ASSEMBLY_LOAD_DEBUG
 #include <config.h>
@@ -80,7 +81,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 140
+#define MONO_CORLIB_VERSION 148
 
 typedef struct
 {
@@ -118,6 +119,9 @@ get_shadow_assembly_location_base (MonoDomain *domain, MonoError *error);
 
 static MonoLoadFunc load_function = NULL;
 
+/* Lazy class loading functions */
+static GENERATE_GET_CLASS_WITH_CACHE (assembly, System.Reflection, Assembly)
+
 void
 mono_install_runtime_load (MonoLoadFunc func)
 {
@@ -177,7 +181,9 @@ create_domain_objects (MonoDomain *domain)
        string_vt = mono_class_vtable (domain, mono_defaults.string_class);
        string_empty_fld = mono_class_get_field_from_name (mono_defaults.string_class, "Empty");
        g_assert (string_empty_fld);
-       mono_field_static_set_value (string_vt, string_empty_fld, mono_string_intern (mono_string_new (domain, "")));
+       MonoString *empty_str = mono_string_intern_checked (mono_string_new (domain, ""), &error);
+       mono_error_assert_ok (&error);
+       mono_field_static_set_value (string_vt, string_empty_fld, empty_str);
 
        /*
         * Create an instance early since we can't do it when there is no memory.
@@ -223,14 +229,22 @@ create_domain_objects (MonoDomain *domain)
  *
  */
 void
-mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
-                  MonoThreadAttachCB attach_cb)
+mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb, MonoThreadAttachCB attach_cb)
 {
        MonoError error;
+       mono_runtime_init_checked (domain, start_cb, attach_cb, &error);
+       mono_error_cleanup (&error);
+}
+
+void
+mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoThreadAttachCB attach_cb, MonoError *error)
+{
        MonoAppDomainSetup *setup;
        MonoAppDomain *ad;
        MonoClass *klass;
 
+       mono_error_init (error);
+
        mono_portability_helpers_init ();
        
        mono_gc_base_init ();
@@ -244,17 +258,18 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        mono_install_assembly_postload_search_hook ((MonoAssemblySearchFunc)mono_domain_assembly_postload_search, GUINT_TO_POINTER (FALSE));
        mono_install_assembly_postload_refonly_search_hook ((MonoAssemblySearchFunc)mono_domain_assembly_postload_search, GUINT_TO_POINTER (TRUE));
        mono_install_assembly_load_hook (mono_domain_fire_assembly_load, NULL);
-       mono_install_lookup_dynamic_token (mono_reflection_lookup_dynamic_token);
 
        mono_thread_init (start_cb, attach_cb);
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
-       setup = (MonoAppDomainSetup *) mono_object_new_pinned (domain, klass, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
+       setup = (MonoAppDomainSetup *) mono_object_new_pinned (domain, klass, error);
+       return_if_nok (error);
+
+       klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomain");
+
+       ad = (MonoAppDomain *) mono_object_new_pinned (domain, klass, error);
+       return_if_nok (error);
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
-       ad = (MonoAppDomain *) mono_object_new_pinned (domain, klass, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
        ad->data = domain;
        domain->domain = ad;
        domain->setup = setup;
@@ -270,7 +285,8 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        mono_gc_init ();
 
        /* contexts use GC handles, so they must be initialized after the GC */
-       mono_context_init (domain);
+       mono_context_init_checked (domain, error);
+       return_if_nok (error);
        mono_context_set (domain->default_context);
 
 #ifndef DISABLE_SOCKETS
@@ -291,18 +307,20 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
 static int
 mono_get_corlib_version (void)
 {
+       MonoError error;
        MonoClass *klass;
        MonoClassField *field;
        MonoObject *value;
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System", "Environment");
+       klass = mono_class_load_from_name (mono_defaults.corlib, "System", "Environment");
        mono_class_init (klass);
        field = mono_class_get_field_from_name (klass, "mono_corlib_version");
        if (!field)
                return -1;
        if (! (field->type->attrs & FIELD_ATTRIBUTE_STATIC))
                return -1;
-       value = mono_field_get_value_object (mono_domain_get (), field, NULL);
+       value = mono_field_get_value_object_checked (mono_domain_get (), field, NULL, &error);
+       mono_error_assert_ok (&error);
        return *(gint32*)((gchar*)value + sizeof (MonoObject));
 }
 
@@ -334,12 +352,22 @@ void
 mono_context_init (MonoDomain *domain)
 {
        MonoError error;
+       mono_context_init_checked (domain, &error);
+       mono_error_cleanup (&error);
+}
+
+void
+mono_context_init_checked (MonoDomain *domain, MonoError *error)
+{
        MonoClass *klass;
        MonoAppContext *context;
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System.Runtime.Remoting.Contexts", "Context");
-       context = (MonoAppContext *) mono_object_new_pinned (domain, klass, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_error_init (error);
+
+       klass = mono_class_load_from_name (mono_defaults.corlib, "System.Runtime.Remoting.Contexts", "Context");
+       context = (MonoAppContext *) mono_object_new_pinned (domain, klass, error);
+       return_if_nok (error);
+
        context->domain_id = domain->domain_id;
        context->context_id = 0;
        ves_icall_System_Runtime_Remoting_Contexts_Context_RegisterContext (context);
@@ -405,15 +433,20 @@ mono_domain_create_appdomain (char *friendly_name, char *configuration_file)
        MonoAppDomainSetup *setup;
        MonoClass *klass;
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
+       klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
        setup = (MonoAppDomainSetup *) mono_object_new_checked (mono_domain_get (), klass, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       if (!is_ok (&error))
+               goto fail;
        setup->configuration_file = configuration_file != NULL ? mono_string_new (mono_domain_get (), configuration_file) : NULL;
 
        ad = mono_domain_create_appdomain_internal (friendly_name, setup, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       if (!is_ok (&error))
+               goto fail;
 
        return mono_domain_from_appdomain (ad);
+fail:
+       mono_error_cleanup (&error);
+       return NULL;
 }
 
 /**
@@ -436,37 +469,52 @@ mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *co
 }
 
 static MonoAppDomainSetup*
-copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetup *setup)
+copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetup *setup, MonoError *error)
 {
-       MonoError error;
-       MonoDomain *caller_domain = mono_domain_get ();
-       MonoClass *ads_class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
-       MonoAppDomainSetup *copy = (MonoAppDomainSetup*)mono_object_new_checked (domain, ads_class, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       MonoDomain *caller_domain;
+       MonoClass *ads_class;
+       MonoAppDomainSetup *copy;
+
+       mono_error_init (error);
+
+       caller_domain = mono_domain_get ();
+       ads_class = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
+
+       copy = (MonoAppDomainSetup*)mono_object_new_checked (domain, ads_class, error);
+       return_val_if_nok (error, NULL);
 
        mono_domain_set_internal (domain);
 
-       MONO_OBJECT_SETREF (copy, application_base, mono_marshal_xdomain_copy_value ((MonoObject*)setup->application_base));
-       MONO_OBJECT_SETREF (copy, application_name, mono_marshal_xdomain_copy_value ((MonoObject*)setup->application_name));
-       MONO_OBJECT_SETREF (copy, cache_path, mono_marshal_xdomain_copy_value ((MonoObject*)setup->cache_path));
-       MONO_OBJECT_SETREF (copy, configuration_file, mono_marshal_xdomain_copy_value ((MonoObject*)setup->configuration_file));
-       MONO_OBJECT_SETREF (copy, dynamic_base, mono_marshal_xdomain_copy_value ((MonoObject*)setup->dynamic_base));
-       MONO_OBJECT_SETREF (copy, license_file, mono_marshal_xdomain_copy_value ((MonoObject*)setup->license_file));
-       MONO_OBJECT_SETREF (copy, private_bin_path, mono_marshal_xdomain_copy_value ((MonoObject*)setup->private_bin_path));
-       MONO_OBJECT_SETREF (copy, private_bin_path_probe, mono_marshal_xdomain_copy_value ((MonoObject*)setup->private_bin_path_probe));
-       MONO_OBJECT_SETREF (copy, shadow_copy_directories, mono_marshal_xdomain_copy_value ((MonoObject*)setup->shadow_copy_directories));
-       MONO_OBJECT_SETREF (copy, shadow_copy_files, mono_marshal_xdomain_copy_value ((MonoObject*)setup->shadow_copy_files));
+#define XCOPY_FIELD(dst,field,src,error)                                       \
+       do {                                                            \
+               MonoObject *copied_val = mono_marshal_xdomain_copy_value ((MonoObject*)(src), error); \
+               return_val_if_nok (error, NULL);                        \
+               MONO_OBJECT_SETREF ((dst),field,copied_val);            \
+       } while (0)
+
+       XCOPY_FIELD (copy, application_base, setup->application_base, error);
+       XCOPY_FIELD (copy, application_name, setup->application_name, error);
+       XCOPY_FIELD (copy, cache_path, setup->cache_path, error);
+       XCOPY_FIELD (copy, configuration_file, setup->configuration_file, error);
+       XCOPY_FIELD (copy, dynamic_base, setup->dynamic_base, error);
+       XCOPY_FIELD (copy, license_file, setup->license_file, error);
+       XCOPY_FIELD (copy, private_bin_path, setup->private_bin_path, error);
+       XCOPY_FIELD (copy, private_bin_path_probe, setup->private_bin_path_probe, error);
+       XCOPY_FIELD (copy, shadow_copy_directories, setup->shadow_copy_directories, error);
+       XCOPY_FIELD (copy, shadow_copy_files, setup->shadow_copy_files, error);
        copy->publisher_policy = setup->publisher_policy;
        copy->path_changed = setup->path_changed;
        copy->loader_optimization = setup->loader_optimization;
        copy->disallow_binding_redirects = setup->disallow_binding_redirects;
        copy->disallow_code_downloads = setup->disallow_code_downloads;
-       MONO_OBJECT_SETREF (copy, domain_initializer_args, mono_marshal_xdomain_copy_value ((MonoObject*)setup->domain_initializer_args));
+       XCOPY_FIELD (copy, domain_initializer_args, setup->domain_initializer_args, error);
        copy->disallow_appbase_probe = setup->disallow_appbase_probe;
-       MONO_OBJECT_SETREF (copy, application_trust, mono_marshal_xdomain_copy_value ((MonoObject*)setup->application_trust));
-       MONO_OBJECT_SETREF (copy, configuration_bytes, mono_marshal_xdomain_copy_value ((MonoObject*)setup->configuration_bytes));
-       MONO_OBJECT_SETREF (copy, serialized_non_primitives, mono_marshal_xdomain_copy_value ((MonoObject*)setup->serialized_non_primitives));
+       XCOPY_FIELD (copy, application_trust, setup->application_trust, error);
+       XCOPY_FIELD (copy, configuration_bytes, setup->configuration_bytes, error);
+       XCOPY_FIELD (copy, serialized_non_primitives, setup->serialized_non_primitives, error);
 
+#undef COPY_FIELD
+       
        mono_domain_set_internal (caller_domain);
 
        return copy;
@@ -480,13 +528,15 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
        MonoDomain *data;
        char *shadow_location;
 
-       adclass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
+       mono_error_init (error);
+
+       adclass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomain");
 
        /* FIXME: pin all those objects */
        data = mono_domain_create();
 
        ad = (MonoAppDomain *) mono_object_new_checked (data, adclass, error);
-       if (!mono_error_ok (error)) return NULL;
+       return_val_if_nok (error, NULL);
        ad->data = data;
        data->domain = ad;
        data->friendly_name = g_strdup (friendly_name);
@@ -503,17 +553,25 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
                }
        }
 
-       mono_context_init (data);
+       mono_context_init_checked (data, error);
+       return_val_if_nok (error, NULL);
+
+       data->setup = copy_app_domain_setup (data, setup, error);
+       if (!mono_error_ok (error)) {
+               g_free (data->friendly_name);
+               return NULL;
+       }
 
-       data->setup = copy_app_domain_setup (data, setup);
        mono_domain_set_options_from_config (data);
        add_assemblies_to_domain (data, mono_defaults.corlib->assembly, NULL);
 
 #ifndef DISABLE_SHADOW_COPY
        /*FIXME, guard this for when the debugger is not running */
        shadow_location = get_shadow_assembly_location_base (data, error);
-       if (!mono_error_ok (error))
+       if (!mono_error_ok (error)) {
+               g_free (data->friendly_name);
                return NULL;
+       }
 
        g_free (shadow_location);
 #endif
@@ -566,10 +624,21 @@ MonoReflectionAssembly *
 mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *tb)
 {
        MonoError error;
+       MonoReflectionAssembly *ret = mono_domain_try_type_resolve_checked (domain, name, tb, &error);
+       mono_error_cleanup (&error);
+
+       return ret;
+}
+
+MonoReflectionAssembly *
+mono_domain_try_type_resolve_checked (MonoDomain *domain, char *name, MonoObject *tb, MonoError *error)
+{
+       static MonoMethod *method = NULL;
        MonoReflectionAssembly *ret;
        MonoClass *klass;
        void *params [1];
-       static MonoMethod *method = NULL;
+
+       mono_error_init (error);
 
        g_assert (domain != NULL && ((name != NULL) || (tb != NULL)));
 
@@ -589,8 +658,8 @@ mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *tb)
        else
                *params = tb;
 
-       ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, error);
+       return_val_if_nok (error, NULL);
 
        return ret;
 }
@@ -883,23 +952,20 @@ mono_domain_set_options_from_config (MonoDomain *domain)
 MonoAppDomain *
 ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
 {
+       MonoError error;
+       MonoAppDomain *ad = NULL;
 #ifdef DISABLE_APPDOMAINS
-       mono_set_pending_exception (mono_get_exception_not_supported ("AppDomain creation is not supported on this runtime."));
-       return NULL;
+       mono_error_set_not_supported (&error, "AppDomain creation is not supported on this runtime.");
 #else
-       MonoError error;
        char *fname;
-       MonoAppDomain *ad;
 
        fname = mono_string_to_utf8 (friendly_name);
        ad = mono_domain_create_appdomain_internal (fname, setup, &error);
 
        g_free (fname);
-
-       mono_error_raise_exception (&error);
-
-       return ad;
 #endif
+       mono_error_set_pending_exception (&error);
+       return ad;
 }
 
 MonoArray *
@@ -908,17 +974,12 @@ ves_icall_System_AppDomain_GetAssemblies (MonoAppDomain *ad, MonoBoolean refonly
        MonoError error;
        MonoDomain *domain = ad->data; 
        MonoAssembly* ass;
-       static MonoClass *System_Reflection_Assembly;
        MonoArray *res;
        GSList *tmp;
        int i;
        GPtrArray *assemblies;
 
        mono_error_init (&error);
-       
-       if (!System_Reflection_Assembly)
-               System_Reflection_Assembly = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "Assembly");
 
        /* 
         * Make a copy of the list of assemblies because we can't hold the assemblies
@@ -937,7 +998,9 @@ ves_icall_System_AppDomain_GetAssemblies (MonoAppDomain *ad, MonoBoolean refonly
        }
        mono_domain_assemblies_unlock (domain);
 
-       res = mono_array_new (domain, System_Reflection_Assembly, assemblies->len);
+       res = mono_array_new_checked (domain, mono_class_get_assembly_class (), assemblies->len, &error);
+       if (!is_ok (&error))
+               goto leave;
        for (i = 0; i < assemblies->len; ++i) {
                ass = (MonoAssembly *)g_ptr_array_index (assemblies, i);
                MonoReflectionAssembly *ass_obj = mono_assembly_get_object_checked (domain, ass, &error);
@@ -954,15 +1017,16 @@ leave:
 }
 
 MonoReflectionAssembly *
-mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *requesting, gboolean refonly)
+mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *requesting, gboolean refonly, MonoError *error)
 {
-       MonoError error;
        MonoReflectionAssembly *ret;
        MonoClass *klass;
        MonoMethod *method;
        MonoBoolean isrefonly;
        gpointer params [3];
 
+       mono_error_init (error);
+
        if (mono_runtime_get_no_exec ())
                return NULL;
 
@@ -980,15 +1044,14 @@ mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *
        isrefonly = refonly ? 1 : 0;
        params [0] = fname;
        if (requesting) {
-               params[1] = mono_assembly_get_object_checked (domain, requesting, &error);
-               if (!mono_error_ok (&error))
-                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+               params[1] = mono_assembly_get_object_checked (domain, requesting, error);
+               return_val_if_nok (error, NULL);
        } else
                params [1] = NULL;
        params [2] = &isrefonly;
 
-       ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, error);
+       return_val_if_nok (error, NULL);
 
        return ret;
 }
@@ -997,6 +1060,7 @@ MonoAssembly *
 mono_domain_assembly_postload_search (MonoAssemblyName *aname, MonoAssembly *requesting,
                                                                          gboolean refonly)
 {
+       MonoError error;
        MonoReflectionAssembly *assembly;
        MonoDomain *domain = mono_domain_get ();
        char *aname_str;
@@ -1006,12 +1070,13 @@ mono_domain_assembly_postload_search (MonoAssemblyName *aname, MonoAssembly *req
 
        /* FIXME: We invoke managed code here, so there is a potential for deadlocks */
        str = mono_string_new (domain, aname_str);
+       g_free (aname_str);
        if (!str) {
-               g_free (aname_str);
                return NULL;
        }
-       assembly = mono_try_assembly_resolve (domain, str, requesting, refonly);
-       g_free (aname_str);
+
+       assembly = mono_try_assembly_resolve (domain, str, requesting, refonly, &error);
+       mono_error_cleanup (&error);
 
        if (assembly)
                return assembly->assembly;
@@ -1106,7 +1171,7 @@ mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data)
        *params = ref_assembly;
 
        mono_runtime_invoke_checked (assembly_load_method, domain->domain, params, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_error_cleanup (&error);
 }
 
 /*
@@ -1709,7 +1774,7 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
        if (!mono_error_ok (&error)) {
                mono_error_cleanup (&error);
                g_free (dir_name);
-               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (invalid characters in shadow directory name).");
+               mono_error_set_execution_engine (oerror, "Failed to create shadow copy (invalid characters in shadow directory name).");
                return NULL;
        }
 
@@ -1724,13 +1789,13 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
        shadow = get_shadow_assembly_location (filename, &error);
        if (!mono_error_ok (&error)) {
                mono_error_cleanup (&error);
-               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (invalid characters in file name).");
+               mono_error_set_execution_engine (oerror, "Failed to create shadow copy (invalid characters in file name).");
                return NULL;
        }
 
        if (ensure_directory_exists (shadow) == FALSE) {
                g_free (shadow);
-               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (ensure directory exists).");
+               mono_error_set_execution_engine (oerror, "Failed to create shadow copy (ensure directory exists).");
                return NULL;
        }       
 
@@ -1767,7 +1832,7 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
                if (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND)
                        return NULL; /* file not found, shadow copy failed */
 
-               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (CopyFile).");
+               mono_error_set_execution_engine (oerror, "Failed to create shadow copy (CopyFile).");
                return NULL;
        }
 
@@ -1786,14 +1851,14 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
        
        if (copy_result == FALSE)  {
                g_free (shadow);
-               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy of sibling data (CopyFile).");
+               mono_error_set_execution_engine (oerror, "Failed to create shadow copy of sibling data (CopyFile).");
                return NULL;
        }
 
        /* Create a .ini file containing the original assembly location */
        if (!shadow_copy_create_ini (shadow, filename)) {
                g_free (shadow);
-               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy .ini file.");
+               mono_error_set_execution_engine (oerror, "Failed to create shadow copy .ini file.");
                return NULL;
        }
 
@@ -2047,8 +2112,13 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
 
        if (!parsed) {
                /* This is a parse error... */
-               if (!refOnly)
-                       refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly);
+               if (!refOnly) {
+                       refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
+                       if (!mono_error_ok (&error)) {
+                               mono_error_set_pending_exception (&error);
+                               return NULL;
+                       }
+               }
                return refass;
        }
 
@@ -2057,8 +2127,13 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
 
        if (!ass) {
                /* MS.NET doesn't seem to call the assembly resolve handler for refonly assemblies */
-               if (!refOnly)
-                       refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly);
+               if (!refOnly) {
+                       refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
+                       if (!mono_error_ok (&error)) {
+                               mono_error_set_pending_exception (&error);
+                               return NULL;
+                       }
+               }
                else
                        refass = NULL;
                if (!refass) {
@@ -2079,10 +2154,11 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
 void
 ves_icall_System_AppDomain_InternalUnload (gint32 domain_id)
 {
+       MonoException *exc = NULL;
        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_get_exception_execution_engine ("Failed to unload domain, domain id not found");
                mono_set_pending_exception (exc);
                return;
        }
@@ -2102,7 +2178,9 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id)
        return;
 #endif
 
-       mono_domain_unload (domain);
+       mono_domain_try_unload (domain, (MonoObject**)&exc);
+       if (exc)
+               mono_set_pending_exception (exc);
 }
 
 gboolean
@@ -2139,8 +2217,10 @@ ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad,
        if (!method)
                g_error ("No entry point method found in %s due to %s", image->name, mono_error_get_message (&error));
 
-       if (!args)
-               args = (MonoArray *) mono_array_new (ad->data, mono_defaults.string_class, 0);
+       if (!args) {
+               args = (MonoArray *) mono_array_new_checked (ad->data, mono_defaults.string_class, 0, &error);
+               mono_error_assert_ok (&error);
+       }
 
        return mono_runtime_exec_main (method, (MonoArray *)args, NULL);
 }
@@ -2239,7 +2319,7 @@ ves_icall_System_AppDomain_InternalGetProcessGuid (MonoString* newguid)
                MonoError error;
                MonoString *res = NULL;
                res = mono_string_new_utf16_checked (mono_domain_get (), process_guid, sizeof(process_guid)/2, &error);
-               mono_error_raise_exception (&error);
+               mono_error_set_pending_exception (&error);
                return res;
        }
        memcpy (process_guid, mono_string_chars(newguid), sizeof(process_guid));
@@ -2359,8 +2439,14 @@ unload_thread_main (void *arg)
 
        /* Have to attach to the runtime so shutdown can wait for this thread */
        /* Force it to be attached to avoid racing during shutdown. */
-       thread = mono_thread_attach_full (mono_get_root_domain (), TRUE, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       thread = mono_thread_attach_full (mono_get_root_domain (), TRUE);
+
+       mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Domain unloader"), TRUE, &error);
+       if (!is_ok (&error)) {
+               data->failure_reason = g_strdup (mono_error_get_message (&error));
+               mono_error_cleanup (&error);
+               goto failure;
+       }
 
        /* 
         * FIXME: Abort our parent thread last, so we can return a failure 
@@ -2449,8 +2535,6 @@ mono_domain_unload (MonoDomain *domain)
 {
        MonoObject *exc = NULL;
        mono_domain_try_unload (domain, &exc);
-       if (exc)
-               mono_raise_exception ((MonoException*)exc);
 }
 
 static guint32
@@ -2458,9 +2542,9 @@ guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
 {
        guint32 result;
 
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        result = WaitForSingleObjectEx (handle, timeout, alertable);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
 
        return result;
 }
@@ -2494,7 +2578,6 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
        unload_data *thread_data;
        MonoNativeThreadId tid;
        MonoDomain *caller_domain = mono_domain_get ();
-       char *name;
 
        /* printf ("UNLOAD STARTING FOR %s (%p) IN THREAD 0x%x.\n", domain->friendly_name, domain, mono_native_thread_id_get ()); */
 
@@ -2554,10 +2637,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
        thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, 0, CREATE_SUSPENDED, &tid);
        if (thread_handle == NULL)
                return;
-       name = g_strdup_printf ("Unload thread for domain %x", domain);
-       mono_thread_info_set_name (tid, name);
        mono_thread_info_resume (tid);
-       g_free (name);
 
        /* Wait for the thread */       
        while (!thread_data->done && guarded_wait (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {