Merge pull request #3121 from lambdageek/dev/managed-init_message
authormonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 9 Jun 2016 22:15:10 +0000 (23:15 +0100)
committerGitHub <noreply@github.com>
Thu, 9 Jun 2016 22:15:10 +0000 (23:15 +0100)
Rewriite `MonoMethodMessage::InitMessage` in managed code

Change icall
`System.Runtime.Remoting.Messaging/MonoMethodMessage::InitMessage` to
managed code.

Also update `mono_message_init()` to invoke `InitMessage`.

mcs/class/corlib/System.Runtime.Remoting.Messaging/MonoMethodMessage.cs
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/object.c

index 3b324d1eab7076389642e0a1776b0343f9366ada..ef0b895922c7f91a49102e533202f082c2472962 100644 (file)
@@ -68,8 +68,38 @@ namespace System.Runtime.Remoting.Messaging {
                internal static String CallContextKey = "__CallContext";
                internal static String UriKey           = "__Uri";
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               internal extern void InitMessage (MonoMethod method, object [] out_args);
+               internal void InitMessage (MonoMethod method, object [] out_args)
+               {
+                       this.method = method;
+                       ParameterInfo[] paramInfo = method.GetParametersInternal ();
+                       int param_count = paramInfo.Length;
+                       args = new object[param_count];
+                       arg_types = new byte[param_count];
+                       asyncResult = null;
+                       call_type = CallType.Sync;
+                       names = new string[param_count];
+                       for (int i = 0; i < param_count; i++) {
+                               names[i] = paramInfo[i].Name;
+                       }
+                       bool hasOutArgs = out_args != null;
+                       int j = 0;
+                       for (int i = 0; i < param_count; i++) {
+                               byte arg_type;
+                               bool isOut = paramInfo[i].IsOut;
+                               if (paramInfo[i].ParameterType.IsByRef) {
+                                       if (hasOutArgs)
+                                               args[i] = out_args[j++];
+                                       arg_type = 2; // OUT
+                                       if (!isOut)
+                                               arg_type |= 1; // INOUT
+                               } else {
+                                       arg_type = 1; // IN
+                                       if (isOut)
+                                               arg_type |= 4; // IN, COPY OUT
+                               }
+                               arg_types[i] = arg_type;
+                       }
+               }
 
                public MonoMethodMessage (MethodBase method, object [] out_args)
                {
index 9f413224e0237fb97ec1e9833dd0ce517b31af27..432ddd6bea5c9653957967876a3728bbafdfb1cc 100644 (file)
@@ -706,9 +706,6 @@ ICALL(CONTEXT_2, "ReleaseContext", ves_icall_System_Runtime_Remoting_Contexts_Co
 ICALL_TYPE(ARES, "System.Runtime.Remoting.Messaging.AsyncResult", ARES_1)
 ICALL(ARES_1, "Invoke", ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke)
 
-ICALL_TYPE(MONOMM, "System.Runtime.Remoting.Messaging.MonoMethodMessage", MONOMM_1)
-ICALL(MONOMM_1, "InitMessage", ves_icall_MonoMethodMessage_InitMessage)
-
 #ifndef DISABLE_REMOTING
 ICALL_TYPE(REALP, "System.Runtime.Remoting.Proxies.RealProxy", REALP_1)
 ICALL(REALP_1, "InternalGetProxyType", ves_icall_Remoting_RealProxy_InternalGetProxyType)
index 636d7eab796547ce4fb7d2f79a42a5193f7cad71..d1a6856c9b44e7824e284b4eda349b274817f442 100644 (file)
@@ -7331,16 +7331,6 @@ ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
        return 9;
 }
 
-ICALL_EXPORT void
-ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this_obj, 
-                                        MonoReflectionMethod *method,
-                                        MonoArray *out_args)
-{
-       MonoError error;
-       mono_message_init (mono_object_domain (this_obj), this_obj, method, out_args, &error);
-       mono_error_set_pending_exception (&error);
-}
-
 #ifndef DISABLE_REMOTING
 ICALL_EXPORT MonoBoolean
 ves_icall_IsTransparentProxy (MonoObject *proxy)
index 7e4c9dc4e062b84777f32afaf1ab51e5ddd3ea04..c402b1d20552dfe9b32abfd3eaedcc588020eeaf 100644 (file)
@@ -7580,88 +7580,24 @@ mono_message_init (MonoDomain *domain,
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoClass *object_array_klass;
-       static MonoClass *byte_array_klass;
-       static MonoClass *string_array_klass;
-       mono_error_init (error);
-       MonoMethodSignature *sig = mono_method_signature (method->method);
-       MonoString *name;
-       MonoArray *arr;
-       int i, j;
-       char **names;
-       guint8 arg_type;
-
-       if (!object_array_klass) {
-               MonoClass *klass;
+       static MonoMethod *init_message_method = NULL;
 
-               klass = mono_array_class_get (mono_defaults.byte_class, 1);
-               g_assert (klass);
-               byte_array_klass = klass;
-
-               klass = mono_array_class_get (mono_defaults.string_class, 1);
-               g_assert (klass);
-               string_array_klass = klass;
-
-               klass = mono_array_class_get (mono_defaults.object_class, 1);
-               g_assert (klass);
-
-               mono_atomic_store_release (&object_array_klass, klass);
+       if (!init_message_method) {
+               init_message_method = mono_class_get_method_from_name (mono_defaults.mono_method_message_class, "InitMessage", 2);
+               g_assert (init_message_method != NULL);
        }
 
-       MONO_OBJECT_SETREF (this_obj, method, method);
-
-       arr = mono_array_new_specific_checked (mono_class_vtable (domain, object_array_klass), sig->param_count, error);
-       return_val_if_nok (error, FALSE);
-
-       MONO_OBJECT_SETREF (this_obj, args, arr);
-
-       arr = mono_array_new_specific_checked (mono_class_vtable (domain, byte_array_klass), sig->param_count, error);
-       return_val_if_nok (error, FALSE);
-
-       MONO_OBJECT_SETREF (this_obj, arg_types, arr);
-
-       this_obj->async_result = NULL;
-       this_obj->call_type = CallType_Sync;
-
-       names = g_new (char *, sig->param_count);
-       mono_method_get_param_names (method->method, (const char **) names);
-
-       arr = mono_array_new_specific_checked (mono_class_vtable (domain, string_array_klass), sig->param_count, error);
-       if (!is_ok (error))
-               goto fail;
-
-       MONO_OBJECT_SETREF (this_obj, names, arr);
+       mono_error_init (error);
+       /* FIXME set domain instead? */
+       g_assert (domain == mono_domain_get ());
        
-       for (i = 0; i < sig->param_count; i++) {
-               name = mono_string_new_checked (domain, names [i], error);
-               if (!is_ok (error))
-                       goto fail;
-               mono_array_setref (this_obj->names, i, name);   
-       }
+       gpointer args[2];
 
-       g_free (names);
-       for (i = 0, j = 0; i < sig->param_count; i++) {
-               if (sig->params [i]->byref) {
-                       if (out_args) {
-                               MonoObject* arg = (MonoObject *)mono_array_get (out_args, gpointer, j);
-                               mono_array_setref (this_obj->args, i, arg);
-                               j++;
-                       }
-                       arg_type = 2;
-                       if (!(sig->params [i]->attrs & PARAM_ATTRIBUTE_OUT))
-                               arg_type |= 1;
-               } else {
-                       arg_type = 1;
-                       if (sig->params [i]->attrs & PARAM_ATTRIBUTE_OUT)
-                               arg_type |= 4;
-               }
-               mono_array_set (this_obj->arg_types, guint8, i, arg_type);
-       }
+       args[0] = method;
+       args[1] = out_args;
 
-       return TRUE;
-fail:
-       g_free (names);
-       return FALSE;
+       mono_runtime_invoke_checked (init_message_method, this_obj, args, error);
+       return is_ok (error);
 }
 
 #ifndef DISABLE_REMOTING