Another round of profiler fixes/improvements. PR #2882 (Manually Merged)
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 19 Apr 2016 22:13:09 +0000 (15:13 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 19 Apr 2016 22:13:09 +0000 (15:13 -0700)
https://github.com/mono/mono/pull/2882

mono/metadata/marshal.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/object.h
mono/metadata/remoting.c
mono/mini/debugger-agent.c
mono/mini/mini-runtime.c

index 8815e0cb1696db06b9aa96f527e5962d4667f075..7eeb2587ff2f0a1646624820919cf1a36102355b 100644 (file)
@@ -2979,7 +2979,8 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
                mono_set_pending_exception ((MonoException*)exc);
        }
 
-       mono_method_return_message_restore (method, params, out_args);
+       mono_method_return_message_restore (method, params, out_args, &error);
+       mono_error_set_pending_exception (&error);
        return res;
 }
 
index 17d5eea26ef0a572d6a7ff0ad8c2676f88629860..b5670975766cfd3dd6e31fe26bcafd38e3cadc67 100644 (file)
@@ -620,7 +620,7 @@ mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *
                              MonoDelegate **cb, MonoObject **state);
 
 void
-mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args);
+mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args, MonoError *error);
 
 void
 mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method);
@@ -1444,6 +1444,26 @@ mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mon
 
 void
 mono_upgrade_remote_class (MonoDomain *domain, MonoObject *tproxy, MonoClass *klass);
+
+void*
+mono_load_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, void **res, MonoError *error);
+
+MonoObject *
+mono_load_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field);
+
+MonoObject *
+mono_load_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoError *error);
+
+gboolean
+mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, void* val, MonoError *error);
+
+void
+mono_store_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg);
+
+gboolean
+mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg, MonoError *error);
+
+
 #endif
 
 gpointer
index dc20b4e83212449db9ba9826eb4a0be57d796369..1c4e9b6d1712b9251218eba915c9ab077a514332 100644 (file)
@@ -6096,8 +6096,10 @@ mono_object_isinst_mbyref_checked (MonoObject *obj, MonoClass *klass, MonoError
                gpointer pa [2];
 
                im = mono_class_get_method_from_name (rpklass, "CanCastTo", -1);
-               if (!im)
-                       mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+               if (!im) {
+                       mono_error_set_not_supported (error, "Linked away.");
+                       return NULL;
+               }
                im = mono_object_get_virtual_method (rp, im);
                g_assert (im);
        
@@ -7328,10 +7330,12 @@ mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *
  * Restore results from message based processing back to arguments pointers
  */
 void
-mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args)
+mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
+       mono_error_init (error);
+
        MonoMethodSignature *sig = mono_method_signature (method);
        int i, j, type, size, out_len;
        
@@ -7346,8 +7350,10 @@ mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoAr
 
                if (pt->byref) {
                        char *arg;
-                       if (j >= out_len)
-                               mono_raise_exception (mono_get_exception_execution_engine ("The proxy call returned an incorrect number of output arguments"));
+                       if (j >= out_len) {
+                               mono_error_set_execution_engine (error, "The proxy call returned an incorrect number of output arguments");
+                               return;
+                       }
 
                        arg = (char *)mono_array_get (out_args, gpointer, j);
                        type = pt->type;
@@ -7394,11 +7400,36 @@ mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoAr
 gpointer
 mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer *res)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
        MonoError error;
+       gpointer result = mono_load_remote_field_checked (this_obj, klass, field, res, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+/**
+ * mono_load_remote_field_checked:
+ * @this: pointer to an object
+ * @klass: klass of the object containing @field
+ * @field: the field to load
+ * @res: a storage to store the result
+ * @error: set on error
+ *
+ * This method is called by the runtime on attempts to load fields of
+ * transparent proxy objects. @this points to such TP, @klass is the class of
+ * the object containing @field. @res is a storage location which can be
+ * used to store the result.
+ *
+ * Returns: an address pointing to the value of field.  On failure returns NULL and sets @error.
+ */
+gpointer
+mono_load_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer *res, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
 
        static MonoMethod *getter = NULL;
+
+       mono_error_init (error);
+
        MonoDomain *domain = mono_domain_get ();
        MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
@@ -7417,17 +7448,19 @@ mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *
        
        if (!getter) {
                getter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldGetter", -1);
-               if (!getter)
-                       mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+               if (!getter) {
+                       mono_error_set_not_supported (error, "Linked away.");
+                       return NULL;
+               }
        }
        
        field_class = mono_class_from_mono_type (field->type);
 
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
+       return_val_if_nok (error, NULL);
        out_args = mono_array_new (domain, mono_defaults.object_class, 1);
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, getter, NULL, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, getter, NULL, error);
+       return_val_if_nok (error, NULL);
        mono_message_init (domain, msg, rm, out_args);
 
        full_name = mono_type_get_full_name (klass);
@@ -7435,15 +7468,18 @@ mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *
        mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
+       return_val_if_nok (error, NULL);
 
-       if (exc) mono_raise_exception ((MonoException *)exc);
+       if (exc) {
+               mono_error_set_exception_instance (error, (MonoException *)exc);
+               return NULL;
+       }
 
        if (mono_array_length (out_args) == 0)
                return NULL;
 
-       *res = mono_array_get (out_args, MonoObject *, 0); /* FIXME: GC write abrrier for res */
+       mono_gc_wbarrier_generic_store (res, mono_array_get (out_args, MonoObject *, 0));
 
        if (field_class->valuetype) {
                return ((char *)*res) + sizeof (MonoObject);
@@ -7462,9 +7498,54 @@ mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *
 MonoObject *
 mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
+       MonoError error;
 
+       MonoObject *result = mono_load_remote_field_new_checked (this_obj, klass, field, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+/**
+ * mono_load_remote_field_new_icall:
+ * @this: pointer to an object
+ * @klass: klass of the object containing @field
+ * @field: the field to load
+ *
+ * This method is called by the runtime on attempts to load fields of
+ * transparent proxy objects. @this points to such TP, @klass is the class of
+ * the object containing @field.
+ * 
+ * Returns: a freshly allocated object containing the value of the
+ * field.  On failure returns NULL and throws an exception.
+ */
+MonoObject *
+mono_load_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
+{
        MonoError error;
+       MonoObject *result = mono_load_remote_field_new_checked (this_obj, klass, field, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+/**
+ * mono_load_remote_field_new_checked:
+ * @this: pointer to an object
+ * @klass: klass of the object containing @field
+ * @field: the field to load
+ * @error: set on error.
+ *
+ * This method is called by the runtime on attempts to load fields of
+ * transparent proxy objects. @this points to such TP, @klass is the class of
+ * the object containing @field.
+ * 
+ * Returns: a freshly allocated object containing the value of the field.  On failure returns NULL and sets @error.
+ */
+MonoObject *
+mono_load_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
 
        static MonoMethod *getter = NULL;
        MonoDomain *domain = mono_domain_get ();
@@ -7482,8 +7563,8 @@ mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFie
        if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
                gpointer val;
                if (field_class->valuetype) {
-                       res = mono_object_new_checked (domain, field_class, &error);
-                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+                       res = mono_object_new_checked (domain, field_class, error);
+                       return_val_if_nok (error, NULL);
                        val = ((gchar *) res) + sizeof (MonoObject);
                } else {
                        val = &res;
@@ -7494,16 +7575,18 @@ mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFie
 
        if (!getter) {
                getter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldGetter", -1);
-               if (!getter)
-                       mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+               if (!getter) {
+                       mono_error_set_not_supported (error, "Linked away.");
+                       return NULL;
+               }
        }
        
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
+       return_val_if_nok (error, NULL);
        out_args = mono_array_new (domain, mono_defaults.object_class, 1);
 
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, getter, NULL, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, getter, NULL, error);
+       return_val_if_nok (error, NULL);
        mono_message_init (domain, msg, rm, out_args);
 
        full_name = mono_type_get_full_name (klass);
@@ -7511,10 +7594,13 @@ mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFie
        mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
+       return_val_if_nok (error, NULL);
 
-       if (exc) mono_raise_exception ((MonoException *)exc);
+       if (exc) {
+               mono_error_set_exception_instance (error, (MonoException *)exc);
+               return NULL;
+       }
 
        if (mono_array_length (out_args) == 0)
                res = NULL;
@@ -7538,11 +7624,33 @@ mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFie
 void
 mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer val)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
        MonoError error;
+       (void) mono_store_remote_field_checked (this_obj, klass, field, val, &error);
+       mono_error_cleanup (&error);
+}
+
+/**
+ * mono_store_remote_field_checked:
+ * @this_obj: pointer to an object
+ * @klass: klass of the object containing @field
+ * @field: the field to load
+ * @val: the value/object to store
+ * @error: set on error
+ *
+ * This method is called by the runtime on attempts to store fields of
+ * transparent proxy objects. @this_obj points to such TP, @klass is the class of
+ * the object containing @field. @val is the new value to store in @field.
+ *
+ * Returns: on success returns TRUE, on failure returns FALSE and sets @error.
+ */
+gboolean
+mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer val, MonoError *error)
+{
+       
+       MONO_REQ_GC_UNSAFE_MODE;
 
        static MonoMethod *setter = NULL;
+
        MonoDomain *domain = mono_domain_get ();
        MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
@@ -7552,6 +7660,8 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
        MonoObject *arg;
        char* full_name;
 
+       mono_error_init (error);
+
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
        field_class = mono_class_from_mono_type (field->type);
@@ -7559,26 +7669,28 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
        if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
                if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, val);
                else mono_field_set_value (tp->rp->unwrapped_server, field, *((MonoObject **)val));
-               return;
+               return TRUE;
        }
 
        if (!setter) {
                setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               if (!setter)
-                       mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+               if (!setter) {
+                       mono_error_set_not_supported (error, "Linked away.");
+                       return FALSE;
+               }
        }
 
        if (field_class->valuetype) {
-               arg = mono_value_box_checked (domain, field_class, val, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               arg = mono_value_box_checked (domain, field_class, val, error);
+               return_val_if_nok (error, FALSE);
        } else 
                arg = *((MonoObject **)val);
                
 
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
+       return_val_if_nok (error, FALSE);
+       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error);
+       return_val_if_nok (error, FALSE);
        mono_message_init (domain, msg, rm, NULL);
 
        full_name = mono_type_get_full_name (klass);
@@ -7587,10 +7699,14 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
        mono_array_setref (msg->args, 2, arg);
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
+       return_val_if_nok (error, FALSE);
 
-       if (exc) mono_raise_exception ((MonoException *)exc);
+       if (exc) {
+               mono_error_set_exception_instance (error, (MonoException *)exc);
+               return FALSE;
+       }
+       return TRUE;
 }
 
 /**
@@ -7605,9 +7721,42 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
 void
 mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
+       MonoError error;
+       (void) mono_store_remote_field_new_checked (this_obj, klass, field, arg, &error);
+       mono_error_cleanup (&error);
+}
 
+/**
+ * mono_store_remote_field_new_icall:
+ * @this_obj:
+ * @klass:
+ * @field:
+ * @arg:
+ *
+ * Missing documentation
+ */
+void
+mono_store_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
+{
        MonoError error;
+       (void) mono_store_remote_field_new_checked (this_obj, klass, field, arg, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+/**
+ * mono_store_remote_field_new_checked:
+ * @this_obj:
+ * @klass:
+ * @field:
+ * @arg:
+ * @error:
+ *
+ * Missing documentation
+ */
+gboolean
+mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
 
        static MonoMethod *setter = NULL;
        MonoDomain *domain = mono_domain_get ();
@@ -7618,6 +7767,8 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi
        MonoObject *exc;
        char* full_name;
 
+       mono_error_init (error);
+
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
        field_class = mono_class_from_mono_type (field->type);
@@ -7625,19 +7776,21 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi
        if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
                if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, ((gchar *) arg) + sizeof (MonoObject));
                else mono_field_set_value (tp->rp->unwrapped_server, field, arg);
-               return;
+               return TRUE;
        }
 
        if (!setter) {
                setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               if (!setter)
-                       mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+               if (!setter) {
+                       mono_error_set_not_supported (error, "Linked away.");
+                       return FALSE;
+               }
        }
 
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
+       return_val_if_nok (error, FALSE);
+       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error);
+       return_val_if_nok (error, FALSE);
        mono_message_init (domain, msg, rm, NULL);
 
        full_name = mono_type_get_full_name (klass);
@@ -7646,10 +7799,14 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi
        mono_array_setref (msg->args, 2, arg);
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
+       return_val_if_nok (error, FALSE);
 
-       if (exc) mono_raise_exception ((MonoException *)exc);
+       if (exc) {
+               mono_error_set_exception_instance (error, (MonoException *)exc);
+               return FALSE;
+       }
+       return TRUE;
 }
 #endif
 
index 360dcd0d63188714790752d0e38c6e846496e662..a1bf771426321c89892fa1f33f817b2d27aa0878 100644 (file)
@@ -271,15 +271,19 @@ mono_runtime_set_main_args  (int argc, char* argv[]);
 
 /* The following functions won't be available with mono was configured with remoting disabled. */
 /*#ifndef DISABLE_REMOTING */
+MONO_RT_EXTERNAL_ONLY
 MONO_API void*
 mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, void **res);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoObject *
 mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API void
 mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, void* val);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API void
 mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg);
 
index 6555cdec7a0d49f1e7da05a0cd841ca99bf47139..ea89ddfd8bac8f6db2eb0e2ea903686f44cc4a0d 100644 (file)
@@ -194,6 +194,9 @@ mono_remoting_marshal_init (void)
                register_icall (mono_marshal_xdomain_copy_out_value, "mono_marshal_xdomain_copy_out_value", "void object object", FALSE);
                register_icall (mono_remoting_wrapper, "mono_remoting_wrapper", "object ptr ptr", FALSE);
                register_icall (mono_upgrade_remote_class_wrapper, "mono_upgrade_remote_class_wrapper", "void object object", FALSE);
+               /* mono_load_remote_field_new_icall registered  by mini-runtime.c */
+               /* mono_store_remote_field_new_icall registered  by mini-runtime.c */
+
        }
 
        icalls_registered = TRUE;
@@ -376,7 +379,8 @@ mono_remoting_wrapper (MonoMethod *method, gpointer *params)
                                        /* runtime_invoke expects a boxed instance */
                                        if (mono_class_is_nullable (mono_class_from_mono_type (sig->params [i]))) {
                                                mparams[i] = mono_nullable_box ((guint8 *)params [i], klass, &error);
-                                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                                               if (!is_ok (&error))
+                                                       goto fail;
                                        } else
                                                mparams[i] = params [i];
                                }
@@ -386,7 +390,8 @@ mono_remoting_wrapper (MonoMethod *method, gpointer *params)
                }
 
                res = mono_runtime_invoke_checked (method, method->klass->valuetype? mono_object_unbox ((MonoObject*)this_obj): this_obj, mparams, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               if (!is_ok (&error))
+                       goto fail;
 
                return res;
        }
@@ -394,16 +399,31 @@ mono_remoting_wrapper (MonoMethod *method, gpointer *params)
        msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
 
        res = mono_remoting_invoke ((MonoObject *)this_obj->rp, msg, &exc, &out_args, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       if (!is_ok (&error))
+               goto fail;
 
-       if (exc)
-               mono_raise_exception ((MonoException *)exc);
+       if (exc) {
+               mono_error_init (&error);
+               mono_error_set_exception_instance (&error, (MonoException *)exc);
+               goto fail;
+       }
 
-       mono_method_return_message_restore (method, params, out_args);
+       mono_method_return_message_restore (method, params, out_args, &error);
+       if (!is_ok (&error)) goto fail;
 
        return res;
+fail:
+       /* This icall will be called from managed code, and more over
+        * from a protected wrapper so interruptions such as pending
+        * exceptions will not be honored.  (See
+        * is_running_protected_wrapper () in threads.c and
+        * mono_marshal_get_remoting_invoke () in remoting.c)
+        */
+       mono_error_raise_exception (&error);
+       return NULL;
 } 
 
+
 MonoMethod *
 mono_marshal_get_remoting_invoke (MonoMethod *method)
 {
@@ -451,6 +471,11 @@ mono_marshal_get_remoting_invoke (MonoMethod *method)
        mono_mb_emit_ptr (mb, method);
        mono_mb_emit_ldloc (mb, params_var);
        mono_mb_emit_icall (mb, mono_remoting_wrapper);
+       // FIXME: this interrupt checkpoint code is a no-op since 'mb'
+       //  is a MONO_WRAPPER_REMOTING_INVOKE, and
+       //  mono_thread_interruption_checkpoint_request (FALSE)
+       //  considers such wrappers "protected" and always returns
+       //  NULL as if there's no pending interruption.
        mono_marshal_emit_thread_interrupt_checkpoint (mb);
 
        if (sig->ret->type == MONO_TYPE_VOID) {
@@ -534,8 +559,10 @@ mono_marshal_set_domain_by_id (gint32 id, MonoBoolean push)
        MonoDomain *current_domain = mono_domain_get ();
        MonoDomain *domain = mono_domain_get_by_id (id);
 
-       if (!domain || !mono_domain_set (domain, FALSE))        
-               mono_raise_exception (mono_get_exception_appdomain_unloaded ());
+       if (!domain || !mono_domain_set (domain, FALSE)) {
+               mono_set_pending_exception (mono_get_exception_appdomain_unloaded ());
+               return 0;
+       }
 
        if (push)
                mono_thread_push_appdomain_ref (domain);
@@ -1285,7 +1312,7 @@ mono_marshal_get_remoting_invoke_with_check (MonoMethod *method)
 MonoMethod *
 mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass)
 {
-       MonoMethodSignature *sig, *csig;
+       MonoMethodSignature *sig;
        MonoMethodBuilder *mb;
        MonoMethod *res;
        static MonoMethod* cached = NULL;
@@ -1312,15 +1339,7 @@ mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass)
        mono_mb_emit_ldarg (mb, 1);
        mono_mb_emit_ldarg (mb, 2);
 
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 3);
-       csig->params [0] = &mono_defaults.object_class->byval_arg;
-       csig->params [1] = &mono_defaults.int_class->byval_arg;
-       csig->params [2] = &mono_defaults.int_class->byval_arg;
-       csig->ret = &mono_defaults.object_class->byval_arg;
-       csig->pinvoke = 1;
-
-       mono_mb_emit_native_call (mb, csig, mono_load_remote_field_new);
-       mono_marshal_emit_thread_interrupt_checkpoint (mb);
+       mono_mb_emit_icall (mb, mono_load_remote_field_new_icall);
 
        mono_mb_emit_byte (mb, CEE_RET);
 #endif
@@ -1643,7 +1662,7 @@ mono_marshal_get_ldflda_wrapper (MonoType *type)
 MonoMethod *
 mono_marshal_get_stfld_remote_wrapper (MonoClass *klass)
 {
-       MonoMethodSignature *sig, *csig;
+       MonoMethodSignature *sig;
        MonoMethodBuilder *mb;
        MonoMethod *res;
        static MonoMethod *cached = NULL;
@@ -1672,16 +1691,7 @@ mono_marshal_get_stfld_remote_wrapper (MonoClass *klass)
        mono_mb_emit_ldarg (mb, 2);
        mono_mb_emit_ldarg (mb, 3);
 
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 4);
-       csig->params [0] = &mono_defaults.object_class->byval_arg;
-       csig->params [1] = &mono_defaults.int_class->byval_arg;
-       csig->params [2] = &mono_defaults.int_class->byval_arg;
-       csig->params [3] = &mono_defaults.object_class->byval_arg;
-       csig->ret = &mono_defaults.void_class->byval_arg;
-       csig->pinvoke = 1;
-
-       mono_mb_emit_native_call (mb, csig, mono_store_remote_field_new);
-       mono_marshal_emit_thread_interrupt_checkpoint (mb);
+       mono_mb_emit_icall (mb, mono_store_remote_field_new_icall);
 
        mono_mb_emit_byte (mb, CEE_RET);
 #endif
index c7e18a0f0d9af49c4a515e255662d5781568a4e1..5b05e57c90e39af906a32a24d9f876a0e900d337 100644 (file)
@@ -9255,6 +9255,7 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 static ErrorCode
 object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 {
+       MonoError error;
        int objid;
        ErrorCode err;
        MonoObject *obj;
@@ -9332,7 +9333,11 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
                                if (remote_obj) {
 #ifndef DISABLE_REMOTING
-                                       field_value = mono_load_remote_field(obj, obj_type, f, &field_storage);
+                                       field_value = mono_load_remote_field_checked(obj, obj_type, f, &field_storage, &error);
+                                       if (!is_ok (&error)) {
+                                               mono_error_cleanup (&error); /* FIXME report the error */
+                                               return ERR_INVALID_OBJECT;
+                                       }
 #else
                                        g_assert_not_reached ();
 #endif
index 0202dac350f4636a05fe6390fceab795510644ad..40163d01d7ffbb2c46cf1383b55c84352b22ff37 100644 (file)
@@ -3901,8 +3901,8 @@ register_icalls (void)
        register_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", "object", FALSE);
        register_icall (mono_thread_force_interruption_checkpoint_noraise, "mono_thread_force_interruption_checkpoint_noraise", "object", FALSE);
 #ifndef DISABLE_REMOTING
-       register_icall (mono_load_remote_field_new, "mono_load_remote_field_new", "object object ptr ptr", FALSE);
-       register_icall (mono_store_remote_field_new, "mono_store_remote_field_new", "void object ptr ptr object", FALSE);
+       register_icall (mono_load_remote_field_new_icall, "mono_load_remote_field_new_icall", "object object ptr ptr", FALSE);
+       register_icall (mono_store_remote_field_new_icall, "mono_store_remote_field_new_icall", "void object ptr ptr object", FALSE);
 #endif
 
 #if defined(__native_client__) || defined(__native_client_codegen__)