[runtime] Set pending, don't raise, in object.c icalls
[mono.git] / mono / metadata / appdomain.c
index 226e0071784a78ae6c680f8688306f2dfbe67d4c..0d8e577c9d4400e57a7b020d18b11bfc20f7b500 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 143
+#define MONO_CORLIB_VERSION 145
 
 typedef struct
 {
@@ -180,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.
@@ -255,7 +258,6 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
        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);
 
@@ -305,6 +307,7 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
 static int
 mono_get_corlib_version (void)
 {
+       MonoError error;
        MonoClass *klass;
        MonoClassField *field;
        MonoObject *value;
@@ -316,7 +319,8 @@ mono_get_corlib_version (void)
                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));
 }
 
@@ -431,13 +435,18 @@ mono_domain_create_appdomain (char *friendly_name, char *configuration_file)
 
        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;
 }
 
 /**
@@ -934,23 +943,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 *
@@ -1053,18 +1059,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, &error);
-       if (!mono_error_ok (&error)) {
-               g_free (aname_str);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
-       }
-
-       g_free (aname_str);
+       mono_error_cleanup (&error);
 
        if (assembly)
                return assembly->assembly;
@@ -1159,7 +1160,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);
 }
 
 /*
@@ -1762,7 +1763,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;
        }
 
@@ -1777,13 +1778,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;
        }       
 
@@ -1820,7 +1821,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;
        }
 
@@ -1839,14 +1840,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;
        }
 
@@ -2142,10 +2143,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;
        }
@@ -2165,7 +2167,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
@@ -2302,7 +2306,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));
@@ -2423,7 +2427,17 @@ 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 */
+       if (!is_ok (&error)) {
+               data->failure_reason = g_strdup (mono_error_get_message (&error));
+               mono_error_cleanup (&error);
+               goto failure;
+       }
+       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 
@@ -2512,8 +2526,6 @@ mono_domain_unload (MonoDomain *domain)
 {
        MonoObject *exc = NULL;
        mono_domain_try_unload (domain, &exc);
-       if (exc)
-               mono_raise_exception ((MonoException*)exc);
 }
 
 static guint32