[runtime] Use MonoError for mono_get_exception_type_initialization, mono_get_exceptio...
authorLudovic Henry <ludovic@xamarin.com>
Fri, 26 Feb 2016 13:32:09 +0000 (13:32 +0000)
committerLudovic Henry <ludovic@xamarin.com>
Wed, 2 Mar 2016 13:27:26 +0000 (13:27 +0000)
mono/metadata/Makefile.am
mono/metadata/exception-internals.h [new file with mode: 0644]
mono/metadata/exception.c
mono/metadata/exception.h
mono/metadata/icall.c
mono/metadata/object.c
mono/mini/mini-exceptions.c

index ff8b646fbd6bdba9095bb14d71ecbc9f92f78e73..cdf42e498d982b6ce989de73960b1abd62513a85 100644 (file)
@@ -125,6 +125,7 @@ common_sources = \
        environment.h           \
        exception.c             \
        exception.h             \
+       exception-internals.h   \
        file-io.c               \
        file-io.h               \
        filewatcher.c           \
diff --git a/mono/metadata/exception-internals.h b/mono/metadata/exception-internals.h
new file mode 100644 (file)
index 0000000..60c2ae0
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _MONO_METADATA_EXCEPTION_INTERNALS_H_
+#define _MONO_METADATA_EXCEPTION_INTERNALS_H_
+
+#include <glib.h>
+
+#include <mono/metadata/object.h>
+#include <mono/utils/mono-error.h>
+
+MonoException *
+mono_get_exception_type_initialization_checked (const gchar *type_name, MonoException *inner, MonoError *error);
+
+MonoException *
+mono_get_exception_reflection_type_load_checked (MonoArray *types, MonoArray *exceptions, MonoError *error);
+
+MonoException *
+mono_get_exception_runtime_wrapped_checked (MonoObject *wrapped_exception, MonoError *error);
+
+#endif
\ No newline at end of file
index a66c9d723d15c63aa04c2d9d27ffafe3659c34b9..f84219678aa08cece25b0768cfea5ac1e62aa445 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <glib.h>
 #include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
 
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/metadata-internals.h>
@@ -107,9 +108,8 @@ mono_exception_from_token (MonoImage *image, guint32 token)
 }
 
 static MonoException *
-create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2)
+create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2, MonoError *error)
 {
-       MonoError error;
        MonoDomain *domain = mono_domain_get ();
        MonoMethod *method = NULL;
        MonoObject *o;
@@ -121,8 +121,8 @@ create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2)
        if (a2 != NULL)
                count++;
        
-       o = mono_object_new_checked (domain, klass, &error);
-       mono_error_assert_ok (&error);
+       o = mono_object_new_checked (domain, klass, error);
+       mono_error_assert_ok (error);
 
        iter = NULL;
        while ((m = mono_class_get_methods (klass, &iter))) {
@@ -145,8 +145,8 @@ create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2)
        args [0] = a1;
        args [1] = a2;
 
-       mono_runtime_invoke_checked (method, o, args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_runtime_invoke_checked (method, o, args, error);
+       return_val_if_nok (error, NULL);
 
        return (MonoException *) o;
 }
@@ -168,9 +168,16 @@ MonoException *
 mono_exception_from_name_two_strings (MonoImage *image, const char *name_space,
                                      const char *name, MonoString *a1, MonoString *a2)
 {
-       MonoClass *klass = mono_class_load_from_name (image, name_space, name);
+       MonoError error;
+       MonoClass *klass;
+       MonoException *ret;
 
-       return create_exception_two_strings (klass, a1, a2);
+       klass = mono_class_load_from_name (image, name_space, name);
+
+       ret = create_exception_two_strings (klass, a1, a2, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+       return ret;
 }
 
 /**
@@ -209,10 +216,16 @@ mono_exception_from_token_two_strings (MonoImage *image, guint32 token,
                                                                           MonoString *a1, MonoString *a2)
 {
        MonoError error;
-       MonoClass *klass = mono_class_get_checked (image, token, &error);
-       g_assert (mono_error_ok (&error)); /* FIXME handle the error. */
+       MonoClass *klass;
+       MonoException *ret;
+
+       klass = mono_class_get_checked (image, token, &error);
+       mono_error_assert_ok (&error); /* FIXME handle the error. */
+
+       ret = create_exception_two_strings (klass, a1, a2, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
-       return create_exception_two_strings (klass, a1, a2);
+       return ret;
 }
 
 /**
@@ -577,6 +590,18 @@ MonoException *
 mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
 {
        MonoError error;
+       MonoException *ret = mono_get_exception_type_initialization_checked (type_name, inner, &error);
+       if (!is_ok (&error)) {
+               mono_error_cleanup (&error);
+               return NULL;
+       }
+
+       return ret;
+}
+
+MonoException *
+mono_get_exception_type_initialization_checked (const gchar *type_name, MonoException *inner, MonoError *error)
+{
        MonoClass *klass;
        gpointer args [2];
        MonoObject *exc;
@@ -602,10 +627,11 @@ mono_get_exception_type_initialization (const gchar *type_name, MonoException *i
        args [0] = mono_string_new (mono_domain_get (), type_name);
        args [1] = inner;
 
-       exc = mono_object_new_checked (mono_domain_get (), klass, &error);
-       mono_error_assert_ok (&error);
-       mono_runtime_invoke_checked (method, exc, args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       exc = mono_object_new_checked (mono_domain_get (), klass, error);
+       mono_error_assert_ok (error);
+
+       mono_runtime_invoke_checked (method, exc, args, error);
+       return_val_if_nok (error, NULL);
 
        return (MonoException *) exc;
 }
@@ -752,6 +778,18 @@ MonoException *
 mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions)
 {
        MonoError error;
+       MonoException *ret = mono_get_exception_reflection_type_load_checked (types, exceptions, &error);
+       if (is_ok (&error)) {
+               mono_error_cleanup (&error);
+               return NULL;
+       }
+
+       return ret;
+}
+
+MonoException *
+mono_get_exception_reflection_type_load_checked (MonoArray *types, MonoArray *exceptions, MonoError *error)
+{
        MonoClass *klass;
        gpointer args [2];
        MonoObject *exc;
@@ -778,11 +816,11 @@ mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions
        args [0] = types;
        args [1] = exceptions;
 
-       exc = mono_object_new_checked (mono_domain_get (), klass, &error);
-       mono_error_assert_ok (&error);
+       exc = mono_object_new_checked (mono_domain_get (), klass, error);
+       mono_error_assert_ok (error);
 
-       mono_runtime_invoke_checked (method, exc, args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_runtime_invoke_checked (method, exc, args, error);
+       return_val_if_nok (error, NULL);
 
        return (MonoException *) exc;
 }
@@ -791,6 +829,18 @@ MonoException *
 mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception)
 {
        MonoError error;
+       MonoException *ret = mono_get_exception_runtime_wrapped_checked (wrapped_exception, &error);
+       if (!is_ok (&error)) {
+               mono_error_cleanup (&error);
+               return NULL;
+       }
+
+       return ret;
+}
+
+MonoException *
+mono_get_exception_runtime_wrapped_checked (MonoObject *wrapped_exception, MonoError *error)
+{
        MonoClass *klass;
        MonoObject *o;
        MonoMethod *method;
@@ -799,16 +849,17 @@ mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception)
 
        klass = mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");
 
-       o = mono_object_new_checked (domain, klass, &error);
-       g_assert (o != NULL && mono_error_ok (&error)); /* FIXME don't swallow the error */
+       o = mono_object_new_checked (domain, klass, error);
+       mono_error_assert_ok (error);
+       g_assert (o != NULL);
 
        method = mono_class_get_method_from_name (klass, ".ctor", 1);
        g_assert (method);
 
        params [0] = wrapped_exception;
 
-       mono_runtime_invoke_checked (method, o, params, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_runtime_invoke_checked (method, o, params, error);
+       return_val_if_nok (error, NULL);
 
        return (MonoException *)o;
 }      
index a03bde43f0e42a5a36ba91aa348ef110a7e8d43b..b9b82dd7427943455cfdd4bd0c4a53638f57f262 100644 (file)
@@ -106,6 +106,7 @@ mono_get_exception_file_not_found        (MonoString *fname);
 MONO_API MonoException *
 mono_get_exception_file_not_found2       (const char *msg, MonoString *fname);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoException *
 mono_get_exception_type_initialization (const char *type_name, MonoException *inner);
 
@@ -136,9 +137,11 @@ mono_get_exception_field_access (void);
 MONO_API MonoException *
 mono_get_exception_method_access (void);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoException *
 mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoException *
 mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception);
 
index 82d2c58996f37486b8f9cc672dfb4240ad32197a..5851f37bfbe7bfc95b8a55975605081b6221fec1 100644 (file)
@@ -45,6 +45,7 @@
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
 #include <mono/metadata/file-io.h>
 #include <mono/metadata/console-io.h>
 #include <mono/metadata/mono-route.h>
@@ -5573,7 +5574,11 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
                g_list_free (list);
                list = NULL;
 
-               exc = mono_get_exception_reflection_type_load (res, exl);
+               exc = mono_get_exception_reflection_type_load_checked (res, exl, &error);
+               if (!is_ok (&error)) {
+                       mono_error_set_pending_exception (&error);
+                       return NULL;
+               }
                mono_loader_clear_error ();
                mono_set_pending_exception (exc);
                return NULL;
index 1918ac783fffd673b5cc5dee24b7f4cb093cc219..7695bc75e8033719c660054d6651e5e52bbb3559 100644 (file)
@@ -23,6 +23,7 @@
 #include <mono/metadata/object.h>
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
 #include <mono/metadata/domain-internals.h>
 #include "mono/metadata/metadata-internals.h"
 #include "mono/metadata/class-internals.h"
@@ -233,6 +234,7 @@ get_type_init_exception_for_vtable (MonoVTable *vtable)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
+       MonoError error;
        MonoDomain *domain = vtable->domain;
        MonoClass *klass = vtable->klass;
        MonoException *ex;
@@ -256,8 +258,9 @@ get_type_init_exception_for_vtable (MonoVTable *vtable)
                        full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
                else
                        full_name = g_strdup (klass->name);
-               ex = mono_get_exception_type_initialization (full_name, NULL);
+               ex = mono_get_exception_type_initialization_checked (full_name, NULL, &error);
                g_free (full_name);
+               return_val_if_nok (&error, NULL);
        }
 
        return ex;
@@ -419,8 +422,12 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
                                full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
                        else
                                full_name = g_strdup (klass->name);
-                       mono_error_set_exception_instance (error, mono_get_exception_type_initialization (full_name, exc));
+
+                       MonoException *exc_to_throw = mono_get_exception_type_initialization_checked (full_name, exc, error);
                        g_free (full_name);
+                       return_val_if_nok (error, FALSE);
+
+                       mono_error_set_exception_instance (error, exc_to_throw);
 
                        MonoException *exc_to_store = mono_error_convert_to_exception (error);
                        /* What we really want to do here is clone the error object and store one copy in the
index d1a2cfd23a38ee0da9d757685ee4fecbe95e7a66..cde7e06bf05f165dced94e47bf0cf5f544aebee0 100644 (file)
@@ -52,6 +52,7 @@
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/reflection-internals.h>
 #include <mono/metadata/gc-internals.h>
@@ -1606,7 +1607,8 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
 
        if (!mono_object_isinst (obj, mono_defaults.exception_class)) {
                non_exception = obj;
-               obj = (MonoObject *)mono_get_exception_runtime_wrapped (obj);
+               obj = (MonoObject *)mono_get_exception_runtime_wrapped_checked (obj, &error);
+               mono_error_assert_ok (&error);
        }
 
        mono_ex = (MonoException*)obj;
@@ -2876,11 +2878,14 @@ mono_jinfo_get_epilog_size (MonoJitInfo *ji)
 static void
 throw_exception (MonoObject *ex, gboolean rethrow)
 {
+       MonoError error;
        MonoJitTlsData *jit_tls = mono_get_jit_tls ();
        MonoException *mono_ex;
 
-       if (!mono_object_isinst (ex, mono_defaults.exception_class))
-               mono_ex = mono_get_exception_runtime_wrapped (ex);
+       if (!mono_object_isinst (ex, mono_defaults.exception_class)) {
+               mono_ex = mono_get_exception_runtime_wrapped_checked (ex, &error);
+               mono_error_assert_ok (&error);
+       }
        else
                mono_ex = (MonoException*)ex;