[runtime] MonoError-ize mono_runtime_delegate_invoke
authorAleksey Kliger <aleksey@xamarin.com>
Fri, 13 May 2016 21:35:40 +0000 (17:35 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Wed, 18 May 2016 19:40:26 +0000 (15:40 -0400)
Mark it external only.  Runtime can use
mono_runtime_delegate_invoke_checked or mono_runtime_delegate_try_invoke.

mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/object.h
mono/metadata/runtime.c
mono/metadata/threads.c

index 2587d877e642b6d6bb6a204bc8fe65f4104c7492..27085b47f8e81eaec124b36cce0fb0efae1b4180 100644 (file)
@@ -1709,6 +1709,14 @@ mono_runtime_invoke_checked (MonoMethod *method, void *obj, void **params, MonoE
 void* 
 mono_compile_method_checked (MonoMethod *method, MonoError *error);
 
+MonoObject*
+mono_runtime_delegate_try_invoke (MonoObject *delegate, void **params,
+                                 MonoObject **exc, MonoError *error);
+
+MonoObject*
+mono_runtime_delegate_invoke_checked (MonoObject *delegate, void **params,
+                                     MonoError *error);
+
 MonoArray*
 mono_runtime_get_main_args_checked (MonoError *error);
 
index a211180eff461d9268cb6299d732496d89ffe046..0fe846451ae73f7b16401d9fc1eb7bea2b54d003 100644 (file)
@@ -3966,6 +3966,44 @@ mono_runtime_delegate_invoke (MonoObject *delegate, void **params, MonoObject **
        MONO_REQ_GC_UNSAFE_MODE;
 
        MonoError error;
+       if (exc) {
+               MonoObject *result = mono_runtime_delegate_try_invoke (delegate, params, exc, &error);
+               if (*exc) {
+                       mono_error_cleanup (&error);
+                       return NULL;
+               } else {
+                       if (!is_ok (&error))
+                               *exc = (MonoObject*)mono_error_convert_to_exception (&error);
+                       return result;
+               }
+       } else {
+               MonoObject *result = mono_runtime_delegate_invoke_checked (delegate, params, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               return result;
+       }
+}
+
+/**
+ * mono_runtime_delegate_try_invoke:
+ * @delegate: pointer to a delegate object.
+ * @params: parameters for the delegate.
+ * @exc: Pointer to the exception result.
+ * @error: set on error
+ *
+ * Invokes the delegate method @delegate with the parameters provided.
+ *
+ * You can pass NULL as the exc argument if you don't want to
+ * catch exceptions, otherwise, *exc will be set to the exception
+ * thrown, if any.  On failure to execute, @error will be set.
+ * if an exception is thrown, you can't use the
+ * MonoObject* result from the function.
+ */
+MonoObject*
+mono_runtime_delegate_try_invoke (MonoObject *delegate, void **params, MonoObject **exc, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
        MonoMethod *im;
        MonoClass *klass = delegate->vtable->klass;
        MonoObject *o;
@@ -3975,19 +4013,32 @@ mono_runtime_delegate_invoke (MonoObject *delegate, void **params, MonoObject **
                g_error ("Could not lookup delegate invoke method for delegate %s", mono_type_get_full_name (klass));
 
        if (exc) {
-               o = mono_runtime_try_invoke (im, delegate, params, exc, &error);
-               if (*exc == NULL && !mono_error_ok (&error))
-                       *exc = (MonoObject*) mono_error_convert_to_exception (&error);
-               else
-                       mono_error_cleanup (&error);
+               o = mono_runtime_try_invoke (im, delegate, params, exc, error);
        } else {
-               o = mono_runtime_invoke_checked (im, delegate, params, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               o = mono_runtime_invoke_checked (im, delegate, params, error);
        }
 
        return o;
 }
 
+/**
+ * mono_runtime_delegate_invoke_checked:
+ * @delegate: pointer to a delegate object.
+ * @params: parameters for the delegate.
+ * @error: set on error
+ *
+ * Invokes the delegate method @delegate with the parameters provided.
+ *
+ * On failure @error will be set and you can't use the MonoObject*
+ * result from the function.
+ */
+MonoObject*
+mono_runtime_delegate_invoke_checked (MonoObject *delegate, void **params, MonoError *error)
+{
+       mono_error_init (error);
+       return mono_runtime_delegate_try_invoke (delegate, params, NULL, error);
+}
+
 static char **main_args = NULL;
 static int num_main_args = 0;
 
@@ -4414,7 +4465,13 @@ call_unhandled_exception_delegate (MonoDomain *domain, MonoObject *delegate, Mon
        pa [0] = domain->domain;
        pa [1] = create_unhandled_exception_eventargs (exc, &error);
        mono_error_assert_ok (&error);
-       mono_runtime_delegate_invoke (delegate, pa, &e);
+       mono_runtime_delegate_try_invoke (delegate, pa, &e, &error);
+       if (!is_ok (&error)) {
+               if (e == NULL)
+                       e = (MonoObject*)mono_error_convert_to_exception (&error);
+               else
+                       mono_error_cleanup (&error);
+       }
 
        if (domain != current_domain)
                mono_domain_set_internal_with_options (current_domain, FALSE);
@@ -7108,7 +7165,9 @@ ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult
 
        ac = (MonoAsyncCall*) ares->object_data;
        if (!ac) {
-               res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, NULL);
+               res = mono_runtime_delegate_invoke_checked (ares->async_delegate, (void**) &ares->async_state, &error);
+               if (mono_error_set_pending_exception (&error))
+                       return NULL;
        } else {
                gpointer wait_event = NULL;
 
index bf23c26c61a1d1d0da6583be1b80e018799fedbd..63f48ccca626730bcff7bf93b9629df846beefdb 100644 (file)
@@ -254,6 +254,7 @@ mono_get_delegate_begin_invoke (MonoClass *klass);
 MONO_API MonoMethod *
 mono_get_delegate_end_invoke (MonoClass *klass);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoObject*
 mono_runtime_delegate_invoke (MonoObject *delegate, void **params, 
                              MonoObject **exc);
index 1c41c797db4fa2c235cd84398bf04cdf7f45541b..078b4cef997d8ec11653d69df65bba2bd521bf1a 100644 (file)
@@ -57,6 +57,7 @@ mono_runtime_is_shutting_down (void)
 static void
 fire_process_exit_event (MonoDomain *domain, gpointer user_data)
 {
+       MonoError error;
        MonoClassField *field;
        gpointer pa [2];
        MonoObject *delegate, *exc;
@@ -70,7 +71,8 @@ fire_process_exit_event (MonoDomain *domain, gpointer user_data)
 
        pa [0] = domain;
        pa [1] = NULL;
-       mono_runtime_delegate_invoke (delegate, pa, &exc);
+       mono_runtime_delegate_try_invoke (delegate, pa, &exc, &error);
+       mono_error_cleanup (&error);
 }
 
 static void
index 253e9c32c3f4938dc73ab6b1caf66fca406b2d53..103f48f8b663648eb22f4f210b8224306b525b62 100644 (file)
@@ -744,7 +744,8 @@ static guint32 WINAPI start_wrapper_internal(void *data)
                g_assert (start_delegate != NULL);
                args [0] = start_arg;
                /* we may want to handle the exception here. See comment below on unhandled exceptions */
-               mono_runtime_delegate_invoke (start_delegate, args, NULL);
+               mono_runtime_delegate_invoke_checked (start_delegate, args, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
        }
 
        /* If the thread calls ExitThread at all, this remaining code