Merge pull request #3199 from lambdageek/dev/proxy-setter
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Tue, 26 Jul 2016 16:47:45 +0000 (12:47 -0400)
committerGitHub <noreply@github.com>
Tue, 26 Jul 2016 16:47:45 +0000 (12:47 -0400)
[remoting] Convert mono_store_remote_field_new_checked to managed code

mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs
mcs/tools/linker/Descriptors/mscorlib.xml
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/remoting.c
mono/metadata/remoting.h
mono/metadata/wrapper-types.h
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini-runtime.c
mono/mini/mini-trampolines.c

index 74bc4764adcc0f09bae453359ac832b31b46f715..74b8b65b3f17afe89deeb11ffaf5cbe1a9883452 100644 (file)
@@ -81,8 +81,10 @@ namespace System.Runtime.Remoting.Proxies
                                return field.GetValue(o);
                        }
 
-                       object[] inArgs = new object[] { Type.GetTypeFromHandle(typeHandle).FullName,
-                                                         field.Name };
+                       string typeName = Type.GetTypeFromHandle(typeHandle).FullName;
+                       string fieldName = field.Name;
+                       object[] inArgs = new object[] { typeName,
+                                                         fieldName };
                        object[] outArgsMsg = new object[1];
                        MethodInfo minfo = typeof(object).GetMethod("FieldGetter", BindingFlags.NonPublic | BindingFlags.Instance);
                        if (minfo == null)
@@ -95,6 +97,36 @@ namespace System.Runtime.Remoting.Proxies
                                throw exc;
                        return outArgs[0];
                }
+
+               internal void StoreRemoteField (IntPtr classPtr, IntPtr fieldPtr, object arg) {
+                       Mono.RuntimeClassHandle classHandle = new Mono.RuntimeClassHandle (classPtr);
+                       RuntimeFieldHandle fieldHandle = new RuntimeFieldHandle (fieldPtr);
+                       RuntimeTypeHandle typeHandle = classHandle.GetTypeHandle ();
+                       FieldInfo field = FieldInfo.GetFieldFromHandle (fieldHandle);
+
+                       if (InCurrentContext ()) {
+                               object o = _rp._server;
+                               field.SetValue (o, arg);
+                               return;
+                       }
+
+                       string typeName = Type.GetTypeFromHandle (typeHandle).FullName;
+                       string fieldName = field.Name;
+                       object [] inArgs = new object[] { typeName,
+                                                         fieldName,
+                                                         arg };
+                       MethodInfo minfo = typeof(object).GetMethod ("FieldSetter", BindingFlags.NonPublic | BindingFlags.Instance);
+                       if (minfo == null)
+                               throw new MissingMethodException ("System.Object", "FieldSetter");
+
+                       MonoMethodMessage msg = new MonoMethodMessage (minfo, inArgs, null);
+                       object [] outArgs;
+                       Exception exc;
+                       RealProxy.PrivateInvoke (_rp, msg, out exc, out outArgs);
+                       if (exc != null)
+                               throw exc;
+               }
+
        }
 #pragma warning restore 169, 649
        
index bc8fddc327d675bd2ce58402e644d0ee8cbde774..28279d9322a8a3e593b40857f7b9758bfcfa72ce 100644 (file)
                </type>
                <type fullname="System.Runtime.Remoting.Proxies.TransparentProxy" preserve="fields">
                        <method name="LoadRemoteFieldNew" />
+                       <method name="StoreRemoteField" />
                </type>
                <type fullname="System.Runtime.Remoting.RemotingServices">
                        <method name="SerializeCallData" />
index a6e5ab526995458a00bcb978b4ec7f08543b4431..9ce52a3515ab6bb6e9e700d24a8f6fa70b31642c 100644 (file)
@@ -1462,9 +1462,6 @@ mono_load_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mono
 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);
 
index 5abeed72821c95d91b536b504d0dab39dad94c8f..7bb2b43beaf795a85ecf1bcd9c94fb7804a30c98 100644 (file)
@@ -8288,65 +8288,24 @@ mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoCla
        
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoMethod *setter = NULL;
+       mono_error_init (error);
 
        MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
-       MonoMethodMessage *msg;
-       MonoArray *out_args;
-       MonoObject *exc;
        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);
 
-       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 TRUE;
-       }
-
-       if (!setter) {
-               setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               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);
                return_val_if_nok (error, FALSE);
-       } else 
-               arg = *((MonoObject **)val);
-               
-
-       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, error);
-       return_val_if_nok (error, FALSE);
-
-       full_name = mono_type_get_full_name (klass);
-       mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
-       mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
-       mono_array_setref (msg->args, 2, arg);
-       g_free (full_name);
-
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
-       return_val_if_nok (error, FALSE);
-
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException *)exc);
-               return FALSE;
+       } else {
+               arg = *((MonoObject**)val);
        }
-       return TRUE;
+
+       return mono_store_remote_field_new_checked (this_obj, klass, field, arg, error);
 }
 
 /**
@@ -8366,23 +8325,6 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi
        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:
@@ -8398,56 +8340,27 @@ mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mon
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoMethod *setter = NULL;
-       MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
-       MonoClass *field_class;
-       MonoMethodMessage *msg;
-       MonoArray *out_args;
-       MonoObject *exc;
-       char* full_name;
+       static MonoMethod *tp_store = NULL;
 
        mono_error_init (error);
 
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
-       field_class = mono_class_from_mono_type (field->type);
-
-       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 TRUE;
-       }
-
-       if (!setter) {
-               setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               if (!setter) {
+       if (!tp_store) {
+               tp_store = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "StoreRemoteField", -1);
+               if (!tp_store) {
                        mono_error_set_not_supported (error, "Linked away.");
                        return FALSE;
                }
        }
 
-       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, error);
-       return_val_if_nok (error, FALSE);
-
-       full_name = mono_type_get_full_name (klass);
-       mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
-       mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
-       mono_array_setref (msg->args, 2, arg);
-       g_free (full_name);
-
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
-       return_val_if_nok (error, FALSE);
+       gpointer args[3];
+       args [0] = &klass;
+       args [1] = &field;
+       args [2] = arg;
 
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException *)exc);
-               return FALSE;
-       }
-       return TRUE;
+       mono_runtime_invoke_checked (tp_store, this_obj, args, error);
+       return is_ok (error);
 }
 #endif
 
index 62379f245e97f296a16b4a72a252c86bf7d79a84..30595ee5410e1a43cf886966b5e7175899ccf2ff 100644 (file)
@@ -198,7 +198,6 @@ mono_remoting_marshal_init (void)
                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);
                register_icall (mono_compile_method_icall, "mono_compile_method_icall", "ptr ptr", FALSE);
-               /* mono_store_remote_field_new_icall registered  by mini-runtime.c */
 
        }
 
@@ -1619,73 +1618,6 @@ mono_marshal_get_ldflda_wrapper (MonoType *type)
        return res;
 }
 
-/*
- * mono_marshal_get_stfld_remote_wrapper:
- * klass: The type of the field
- *
- *  This function generates a wrapper for calling mono_store_remote_field_new
- * with the appropriate signature.
- * Similarly to mono_marshal_get_ldfld_remote_wrapper () this doesn't depend on the
- * klass argument anymore.
- */
-MonoMethod *
-mono_marshal_get_stfld_remote_wrapper (MonoClass *klass)
-{
-       MonoMethodSignature *sig;
-       MonoMethodBuilder *mb;
-       MonoMethod *res;
-       static MonoMethod *cached = NULL;
-
-       mono_marshal_lock_internal ();
-       if (cached) {
-               mono_marshal_unlock_internal ();
-               return cached;
-       }
-       mono_marshal_unlock_internal ();
-
-       mb = mono_mb_new_no_dup_name (mono_defaults.object_class, "__mono_store_remote_field_new_wrapper", MONO_WRAPPER_STFLD_REMOTE);
-
-       mb->method->save_lmf = 1;
-
-       sig = mono_metadata_signature_alloc (mono_defaults.corlib, 4);
-       sig->params [0] = &mono_defaults.object_class->byval_arg;
-       sig->params [1] = &mono_defaults.int_class->byval_arg;
-       sig->params [2] = &mono_defaults.int_class->byval_arg;
-       sig->params [3] = &mono_defaults.object_class->byval_arg;
-       sig->ret = &mono_defaults.void_class->byval_arg;
-
-#ifndef DISABLE_JIT
-       mono_mb_emit_ldarg (mb, 0);
-       mono_mb_emit_ldarg (mb, 1);
-       mono_mb_emit_ldarg (mb, 2);
-       mono_mb_emit_ldarg (mb, 3);
-
-       mono_mb_emit_icall (mb, mono_store_remote_field_new_icall);
-
-       mono_mb_emit_byte (mb, CEE_RET);
-#endif
-
-       mono_marshal_lock_internal ();
-       res = cached;
-       mono_marshal_unlock_internal ();
-       if (!res) {
-               MonoMethod *newm;
-               newm = mono_mb_create (mb, sig, 6, NULL);
-               mono_marshal_lock_internal ();
-               res = cached;
-               if (!res) {
-                       res = newm;
-                       cached = res;
-                       mono_marshal_unlock_internal ();
-               } else {
-                       mono_marshal_unlock_internal ();
-                       mono_free_method (newm);
-               }
-       }
-       mono_mb_free (mb);
-       
-       return res;
-}
 
 /*
  * mono_marshal_get_stfld_wrapper:
@@ -1706,6 +1638,7 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        WrapperInfo *info;
        char *name;
        int t, pos;
+       static MonoMethod *tp_store = NULL;
 
        type = mono_type_get_underlying_type (type);
        t = type->type;
@@ -1735,6 +1668,13 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        if ((res = mono_marshal_find_in_cache (cache, klass)))
                return res;
 
+#ifndef DISABLE_REMOTING
+       if (!tp_store) {
+               tp_store = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "StoreRemoteField", -1);
+               g_assert (tp_store != NULL);
+       }
+#endif
+
        /* we add the %p pointer value of klass because class names are not unique */
        name = g_strdup_printf ("__stfld_wrapper_%p_%s.%s", klass, klass->name_space, klass->name); 
        mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_STFLD);
@@ -1752,6 +1692,7 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        mono_mb_emit_ldarg (mb, 0);
        pos = mono_mb_emit_proxy_check (mb, CEE_BNE_UN);
 
+#ifndef DISABLE_REMOTING
        mono_mb_emit_ldarg (mb, 0);
        mono_mb_emit_ldarg (mb, 1);
        mono_mb_emit_ldarg (mb, 2);
@@ -1759,9 +1700,10 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        if (klass->valuetype)
                mono_mb_emit_op (mb, CEE_BOX, klass);
 
-       mono_mb_emit_managed_call (mb, mono_marshal_get_stfld_remote_wrapper (klass), NULL);
+       mono_mb_emit_managed_call (mb, tp_store, NULL);
 
        mono_mb_emit_byte (mb, CEE_RET);
+#endif
 
        mono_mb_patch_branch (mb, pos);
 
index 9b495b2fb59f87be44d473aad0f80691a09af3ad..b0307aed93dfe044247ac64fee04393385b97eca 100644 (file)
@@ -38,12 +38,6 @@ mono_marshal_get_ldfld_wrapper (MonoType *type);
 MonoMethod *
 mono_marshal_get_ldflda_wrapper (MonoType *type);
 
-MonoMethod *
-mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass);
-
-MonoMethod *
-mono_marshal_get_stfld_remote_wrapper (MonoClass *klass);
-
 MonoMethod *
 mono_marshal_get_proxy_cancast (MonoClass *klass);
 
index 909113cae8e97077451a2dedf70dea6fbf87b99f..fc2c8954426a32bdba980bdc7f203c66bb8bc205 100644 (file)
@@ -17,7 +17,6 @@ WRAPPER(XDOMAIN_INVOKE, "xdomain-invoke")
 WRAPPER(XDOMAIN_DISPATCH, "xdomain-dispatch")
 WRAPPER(LDFLD, "ldfld")
 WRAPPER(STFLD, "stfld")
-WRAPPER(STFLD_REMOTE, "stfld-remote")
 WRAPPER(SYNCHRONIZED, "synchronized")
 WRAPPER(DYNAMIC_METHOD, "dynamic-method")
 WRAPPER(ISINST, "isinst")
index 7791ec26d0b55fbff726f895120fea3eb16e118b..5719f5f1207d158d57f30b258e1595631142d73d 100644 (file)
@@ -3104,8 +3104,6 @@ encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, guint8
                        encode_klass_ref (acfg, info->d.proxy.klass, p, &p);
                        break;
                }
-               case MONO_WRAPPER_STFLD_REMOTE:
-                       break;
                case MONO_WRAPPER_ALLOC: {
                        /* The GC name is saved once in MonoAotFileInfo */
                        g_assert (info->d.alloc.alloc_type != -1);
@@ -7209,7 +7207,6 @@ can_encode_method (MonoAotCompile *acfg, MonoMethod *method)
                        case MONO_WRAPPER_STFLD:
                        case MONO_WRAPPER_LDFLD:
                        case MONO_WRAPPER_LDFLDA:
-                       case MONO_WRAPPER_STFLD_REMOTE:
                        case MONO_WRAPPER_STELEMREF:
                        case MONO_WRAPPER_ISINST:
                        case MONO_WRAPPER_PROXY_ISINST:
index 14fcfbabc056fbde074805348a4d92c75fdb1133..2f818c6821cef511e12f349739f013f8de8e7116 100644 (file)
@@ -922,9 +922,6 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        }
                        break;
                }
-               case MONO_WRAPPER_STFLD_REMOTE:
-                       ref->method = mono_marshal_get_stfld_remote_wrapper (NULL);
-                       break;
 #endif
                case MONO_WRAPPER_ALLOC: {
                        int atype = decode_value (p, &p);
index dfce66481ea8db4cef11787384c1f03ad25ac634..e1918076a8a97099a952d461b43b0d7e6f9fdfad 100644 (file)
@@ -3776,9 +3776,6 @@ register_icalls (void)
        register_icall (mono_thread_get_undeniable_exception, "mono_thread_get_undeniable_exception", "object", FALSE);
        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_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__)
        register_icall (mono_nacl_gc, "mono_nacl_gc", "void", FALSE);
index 12be87a1fab52deee3d143b7202cbf665e572f47..8c1fe23297bffd8ba8b6ce8c9a6f43e62fff2b78 100644 (file)
@@ -1522,8 +1522,7 @@ mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *e
                if (code)
                        return code;
                if (mono_llvm_only) {
-                       if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST ||
-                               method->wrapper_type == MONO_WRAPPER_STFLD_REMOTE)
+                       if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST)
                                /* These wrappers are not generated */
                                return method_not_found;
                        /* Methods are lazily initialized on first call, so this can't lead recursion */