2002-03-30 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Sat, 30 Mar 2002 16:56:30 +0000 (16:56 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Sat, 30 Mar 2002 16:56:30 +0000 (16:56 -0000)
* x86.brg: impl. REMOTE_FIELD (load fields of remote objects)

* message.c (mono_load_remote_field): impl.

* icall.c (mono_message_init): impl. (code cleanup)
(ves_icall_InternalExecute): impl. FieldGetter

svn path=/trunk/mono/; revision=3517

mono/jit/ChangeLog
mono/jit/jit.c
mono/jit/jit.h
mono/jit/message.c
mono/jit/trampoline.c
mono/jit/x86.brg
mono/metadata/ChangeLog
mono/metadata/icall.c
mono/metadata/reflection.h
mono/tests/remoting1.cs

index c93e5d19659962e628ce9b6b40d339ec73e8a4c3..51c7c546efa17f1cfa3d375021d5e593542c5cff 100644 (file)
@@ -1,7 +1,12 @@
 2002-03-30  Dietmar Maurer  <dietmar@ximian.com>
 
+       * x86.brg: impl. REMOTE_FIELD (load fields of remote objects)
+
+       * message.c (mono_load_remote_field): impl.
+
        * jit.c (mono_analyze_stack): only call marshalbyref methods
        through the vtable.
+       (mono_analyze_stack): consider marshalbyref objects in LDFLD
 
 Fri Mar 29 16:00:27 CET 2002 Paolo Molaro <lupus@ximian.com>
 
index 4ce4d0d3677ce03477e2b7fd5ce517ffaf48ddbf..f0012f02b69ea0cf3f75b608d954611c18976e01 100644 (file)
@@ -1716,17 +1716,24 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                field = mono_class_get_field (klass, token);
                        }
                        g_assert (field);
-
-                       t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
                        
-                       if (klass->valuetype)
-                               t1->data.i = field->offset - sizeof (MonoObject);
-                       else 
-                               t1->data.i = field->offset;
+                       if (klass->marshalbyref) {
+                               t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
+                               t1->data.klass = klass;
+                               t1 = mono_ctree_new (mp, MB_TERM_REMOTE_FIELD, sp [0], t1);
+                               t1->data.field = field;
+                       } else {
+                               t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
 
-                       t1 = mono_ctree_new (mp, MB_TERM_ADD, sp [0], t1);
+                               if (klass->valuetype)
+                                       t1->data.i = field->offset - sizeof (MonoObject);
+                               else 
+                                       t1->data.i = field->offset;
+
+                               t1 = mono_ctree_new (mp, MB_TERM_ADD, sp [0], t1);
+                       }
 
-                       if (!load_addr)
+                       if (!load_addr) 
                                t1 = ctree_create_load (cfg, field->type, t1, &svt, FALSE);
                        else
                                svt = VAL_POINTER;
index a5d25146c1e0b838a201b8050a22ad5de362e066..5884874c6cca085fdd578e71dbd41930ba4b5d0e 100644 (file)
@@ -219,6 +219,13 @@ arch_end_invoke            (MonoObject *this, gpointer handle, ...);
 gpointer
 arch_get_delegate_invoke   (MonoMethod *method, int *size);
 
+gpointer
+mono_load_remote_field     (MonoObject *this, MonoClass *klass, MonoClassField *field);
+
+MonoObject *
+mono_remoting_invoke       (MonoObject *real_proxy, MonoMethodMessage *msg, 
+                           MonoObject **exc, MonoArray **out_args);
+
 /* some handy debugging functions */
 
 void
index baf18e087899976240b4eabc9d6ceb131e93e17b..e3679a973139a4451394fde4158349fcd7d3fe52 100644 (file)
@@ -172,22 +172,8 @@ mono_method_call_message_new (MonoMethod *method, gpointer stack)
        guint8 arg_type;
 
        msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class); 
-
-       msg->method = mono_method_get_object (domain, method);
-
-       msg->args = mono_array_new (domain, mono_defaults.object_class, sig->param_count);
-       msg->arg_types = mono_array_new (domain, mono_defaults.byte_class, sig->param_count);
-
-       names = g_new (char *, sig->param_count);
-       mono_method_get_param_names (method, (const char **) names);
-       msg->names = mono_array_new (domain, mono_defaults.string_class, sig->param_count);
        
-       for (i = 0; i < sig->param_count; i++) {
-                name = mono_string_new (domain, names [i]);
-                mono_array_set (msg->names, gpointer, i, name);        
-       }
-
-       g_free (names);
+       mono_message_init (domain, msg, mono_method_get_object (domain, method), NULL);
 
        /* the first argument is an implizit reference for valuetype 
         * return values */
@@ -204,54 +190,70 @@ mono_method_call_message_new (MonoMethod *method, gpointer stack)
 
                size = mono_type_stack_size (sig->params [i], &align);
 
-               if (sig->params [i]->byref) {
-                       arg_type = 2;
+               if (sig->params [i]->byref)
                        vpos = *((gpointer *)cpos);
-                       if (sig->params [i]->attrs & PARAM_ATTRIBUTE_IN)
-                               arg_type = 1;
-               } else {
+               else 
                        vpos = cpos;
-                       arg_type = 1;
-               }
 
                type = sig->params [i]->type;
                class = mono_class_from_mono_type (sig->params [i]);
 
-               switch (type) {
-               case MONO_TYPE_VOID:
-                       g_assert_not_reached ();
-                       break;
-               case MONO_TYPE_U1:
-               case MONO_TYPE_I1:
-               case MONO_TYPE_BOOLEAN:
-               case MONO_TYPE_U2:
-               case MONO_TYPE_I2:
-               case MONO_TYPE_CHAR:
-               case MONO_TYPE_U:
-               case MONO_TYPE_I:
-               case MONO_TYPE_U4:
-               case MONO_TYPE_I4:
-               case MONO_TYPE_I8:
-               case MONO_TYPE_U8:
-               case MONO_TYPE_R4:
-               case MONO_TYPE_R8:
-               case MONO_TYPE_VALUETYPE:
+               if (class->valuetype)
                        arg = mono_value_box (domain, class, vpos);
-                       break;
-               case MONO_TYPE_STRING:
-               case MONO_TYPE_CLASS: 
-               case MONO_TYPE_ARRAY:
-               case MONO_TYPE_SZARRAY:
+               else 
                        arg = *((MonoObject **)vpos);
-                       break;
-               default:
-                       g_assert_not_reached ();
-               }
-       
+                     
                mono_array_set (msg->args, gpointer, i, arg);
-               mono_array_set (msg->arg_types, guint8, i, arg_type);
                cpos += size;
        }
        
        return msg;
 }
+
+gpointer
+mono_load_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *field)
+{
+       static MonoMethod *getter = NULL;
+       MonoDomain *domain = mono_domain_get ();
+       MonoClass *field_class;
+       MonoMethodMessage *msg;
+       MonoArray *out_args;
+       MonoObject *exc;
+       MonoObject *res;
+
+       g_assert (this->vtable->klass == mono_defaults.transparent_proxy_class);
+
+       if (!getter) {
+               int i;
+
+               for (i = 0; i < mono_defaults.object_class->method.count; ++i) {
+                       MonoMethod *cm = mono_defaults.object_class->methods [i];
+              
+                       if (!strcmp (cm->name, "FieldGetter")) {
+                               getter = cm;
+                               break;
+                       }
+               }
+               g_assert (getter);
+       }
+       
+       field_class = mono_class_from_mono_type (field->type);
+
+       msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
+       out_args = mono_array_new (domain, mono_defaults.object_class, 1);
+       mono_message_init (domain, msg, mono_method_get_object (domain, getter), out_args);
+
+       mono_array_set (msg->args, gpointer, 0, mono_string_new (domain, klass->name));
+       mono_array_set (msg->args, gpointer, 1, mono_string_new (domain, field->name));
+
+       printf ("TEST %p %p %p %p \n", ((MonoTransparentProxy *)this)->rp, msg, &exc, &out_args);
+       mono_remoting_invoke (((MonoTransparentProxy *)this)->rp, msg, &exc, &out_args);
+
+       res = mono_array_get (out_args, MonoObject *, 0);
+
+       if (field_class->valuetype) {
+               printf ("XTEST %d\n", *((int *)(((char *)res) + sizeof (MonoObject))));
+               return ((char *)res) + sizeof (MonoObject);
+       } else
+               return &res;
+}
index baf46ccc9138f9c445987c318e907fbb43a1143f..e1a73d37a0c36eea61ea01760cc5b751f137348c 100644 (file)
 #include "codegen.h"
 #include "message.h"
 
-static void
-arch_remoting_invoke (MonoMethod *method, gpointer ip, gpointer first_arg)
+MonoObject *
+mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, 
+                     MonoObject **exc, MonoArray **out_args)
 {
-       MonoMethodSignature *sig = method->signature;
-       MonoMethodMessage *msg;
-       MonoTransparentProxy *this;
-       MonoObject *res, *exc;
-       MonoArray *out_args;
-       int this_pos = 0;
        static MonoObject *(*invoke) (gpointer, gpointer, MonoObject **, MonoArray **) = NULL;
 
-       //printf ("REMOTING %s.%s:%s\n", method->klass->name_space, method->klass->name,
-       //method->name);
-
-       if (ISSTRUCT (sig->ret))
-               this_pos += 4;
-
-       this = *(MonoTransparentProxy **)(((char *)&first_arg) + this_pos);
-
-       g_assert (((MonoObject *)this)->vtable->klass == mono_defaults.transparent_proxy_class);
-
-       msg = mono_method_call_message_new (method, &first_arg);
-
        /* fixme: make this domain dependent */
        if (!invoke) {
                MonoClass *klass;
@@ -59,8 +42,32 @@ arch_remoting_invoke (MonoMethod *method, gpointer ip, gpointer first_arg)
                g_assert (invoke);
        }
 
+       return invoke (real_proxy, msg, exc, out_args);
+}
+
+static void
+arch_remoting_invoke (MonoMethod *method, gpointer ip, gpointer first_arg)
+{
+       MonoMethodSignature *sig = method->signature;
+       MonoMethodMessage *msg;
+       MonoTransparentProxy *this;
+       MonoObject *res, *exc;
+       MonoArray *out_args;
+       int this_pos = 0;
+
+       //printf ("REMOTING %s.%s:%s\n", method->klass->name_space, method->klass->name,
+       //method->name);
+
+       if (ISSTRUCT (sig->ret))
+               this_pos += 4;
+
+       this = *(MonoTransparentProxy **)(((char *)&first_arg) + this_pos);
+
+       g_assert (((MonoObject *)this)->vtable->klass == mono_defaults.transparent_proxy_class);
+
+       msg = mono_method_call_message_new (method, &first_arg);
 
-       res = invoke (this->rp, msg, &exc, &out_args);
+       res = mono_remoting_invoke (this->rp, msg, &exc, &out_args);
 
        if (exc)
                mono_raise_exception ((MonoException *)exc);
index d02f946fa1a6acc9843c3dbe417854b3c66bc27b..9c248f759592ba5ea62a3d3355521c300e446aab 100644 (file)
@@ -74,6 +74,7 @@ struct _MBTree {
                MonoMethod *m;
                MethodCallInfo *ci;
                MonoClass *klass;
+               MonoClassField *field;
                X86AddressInfo ainfo;
        } data;
 };
@@ -191,6 +192,7 @@ void *MEMCOPY (void *dest, const void *src, size_t n);
 %term CONV_OVF_I2_UN CONV_OVF_I8_UN CONV_OVF_I1_UN 
 %term EXCEPTION THROW RETHROW HANDLER
 %term LDLEN LDELEMA LDFTN LDVIRTFTN LDSTR LDSFLDA
+%term REMOTE_FIELD
 
 #
 # we start at stmt
@@ -612,6 +614,66 @@ reg: LDIND_U4 (addr) {
        PRINT_REG ("LDIND_U4", tree->reg1);
 }
 
+reg: REMOTE_FIELD (reg, CONST_I4) {
+       guint8 *br[2], *pos[2];
+       int treg = X86_EAX;
+       int lreg = tree->left->reg1;
+
+       if (lreg == X86_EAX)
+               treg = X86_EDX;
+
+       if (tree->reg1 != treg)
+               x86_push_reg (s->code, treg);
+
+       x86_mov_reg_membase (s->code, treg, lreg, 0, 4);
+       x86_alu_membase_imm (s->code, X86_CMP, treg, 0, ((int)mono_defaults.transparent_proxy_class));
+       br [0] = s->code; x86_branch8 (s->code, X86_CC_NE, 0, FALSE); /* jump to label0 */
+       pos [0] = s->code;
+
+       /* this is a transparent proxy - remote the call */
+       if (treg != X86_EAX)
+               x86_push_reg (s->code, X86_EAX);
+       if (treg != X86_EDX)
+               x86_push_reg (s->code, X86_EDX);
+       x86_push_reg (s->code, X86_ECX);
+
+       x86_push_imm (s->code, tree->data.field);
+       x86_push_imm (s->code, tree->right->data.klass);
+       x86_push_reg (s->code, lreg);
+       mono_add_jump_info (s, s->code + 1, MONO_JUMP_INFO_ABS, mono_load_remote_field);
+       x86_call_code (s->code, 0);
+       x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 12);
+
+       if (treg != X86_EAX)
+               x86_mov_reg_reg (s->code, treg, X86_EAX, 4);
+
+       x86_pop_reg (s->code, X86_ECX);
+       if (treg != X86_EDX)
+               x86_pop_reg (s->code, X86_EDX);
+       if (treg != X86_EAX)
+               x86_pop_reg (s->code, X86_EAX);
+
+       x86_mov_reg_reg (s->code, tree->reg1, treg, 4);
+
+       br [1] = s->code; x86_jump8 (s->code, 0); /* jump to label1 */
+       pos [1] = s->code;
+       
+       /* label0 */ x86_branch8 (br [0], X86_CC_NE, s->code - pos [0], FALSE);
+       if (tree->right->data.klass->valuetype)
+               x86_lea_membase (s->code, tree->reg1, lreg, 
+                                tree->data.field->offset - sizeof (MonoObject));
+       else 
+               x86_lea_membase (s->code, tree->reg1, lreg, tree->data.field->offset);
+
+       /* label1 */ x86_jump8 (br [1], s->code - pos [1]);
+
+       if (tree->reg1 != treg)
+               x86_pop_reg (s->code, treg);
+
+       //x86_breakpoint (s->code);
+}
+
+
 reg: ADDR_L 5 {
        int offset = g_array_index (s->varinfo, MonoVarInfo, tree->data.i).offset;  
        x86_lea_membase (s->code, tree->reg1, X86_EBP, offset);
index 910beddfa015a6f04269f670e064edd23bbbc0be..df838f6c8ccb0f9832c8f2a16dfd879a8dfc3502 100644 (file)
@@ -1,5 +1,8 @@
 2002-03-30  Dietmar Maurer  <dietmar@ximian.com>
 
+       * icall.c (mono_message_init): impl. (code cleanup)
+       (ves_icall_InternalExecute): impl. FieldGetter
+
        * class.c (mono_class_init): added exerimental EXT_VTABLE_HACK, if
        defined we call all (non-static)methods through the vtable. 
 
index 44891fd0386972c3d5d4e57d6c166ec832df9b59..c408ff01391724b161f1b16ba2564f26328728ff 100644 (file)
@@ -869,10 +869,11 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
                        pa [i] = (char *)(((gpointer *)params->vector)[i]) + sizeof (MonoObject);
                        break;
                case MONO_TYPE_STRING:
+               case MONO_TYPE_OBJECT:
                        pa [i] = (char *)(((gpointer *)params->vector)[i]);
                        break;
                default:
-                       g_error ("type 0x%x not handled in invoke", sig->params [i]->type);
+                       g_error ("type 0x%x not handled in ves_icall_InternalInvoke", sig->params [i]->type);
                }
        }
 
@@ -888,11 +889,42 @@ static MonoObject *
 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs) 
 {
        MonoDomain *domain = mono_domain_get (); 
-       MonoMethodSignature *sig = method->method->signature;
+       MonoMethod *m = method->method;
+       MonoMethodSignature *sig = m->signature;
        MonoArray *out_args;
        MonoObject *result;
        int i, j, outarg_count = 0;
 
+       if (m->klass == mono_defaults.object_class && !strcmp (m->name, "FieldGetter")) {
+               MonoClass *k = this->vtable->klass;
+               MonoString *name = mono_array_get (params, MonoString *, 1);
+               char *str;
+
+               str = mono_string_to_utf8 (name);
+               
+               for (i = 0; i < k->field.count; i++) {
+                       if (!strcmp (k->fields [i].name, str)) {
+                               MonoClass *field_klass =  mono_class_from_mono_type (k->fields [i].type);
+                               if (field_klass->valuetype)
+                                       result = mono_value_box (domain, field_klass,
+                                                                (char *)this + k->fields [i].offset);
+                               else 
+                                       result = *((char *)this + k->fields [i].offset);
+                               
+                               g_assert (result);
+                               out_args = mono_array_new (domain, mono_defaults.object_class, 1);
+                               *outArgs = out_args;
+                               mono_array_set (out_args, gpointer, 0, result);
+                               g_free (str);
+                               return NULL;
+                       }
+               }
+
+               g_free (str);
+               g_assert_not_reached ();
+
+       }
+
        for (i = 0; i < params->bounds->length; i++) {
                if (sig->params [i]->byref) 
                        outarg_count++;
@@ -1878,11 +1910,11 @@ ves_icall_System_Environment_GetCommandLine ()
 
 
 void
-ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this, 
-                                        MonoReflectionMethod *method,
-                                        MonoArray *out_args)
+mono_message_init (MonoDomain *domain,
+                  MonoMethodMessage *this, 
+                  MonoReflectionMethod *method,
+                  MonoArray *out_args)
 {
-       MonoDomain *domain = mono_domain_get ();
        MonoMethodSignature *sig = method->method->signature;
        MonoString *name;
        int i, j;
@@ -1915,7 +1947,7 @@ ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
                        }
                        arg_type = 2;
                        if (sig->params [i]->attrs & PARAM_ATTRIBUTE_IN)
-                               arg_type = 1;
+                               arg_type |= 1;
                } else {
                        arg_type = 1;
                }
@@ -1924,6 +1956,16 @@ ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
        }
 }
 
+static void
+ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this, 
+                                        MonoReflectionMethod *method,
+                                        MonoArray *out_args)
+{
+       MonoDomain *domain = mono_domain_get ();
+       
+       mono_message_init (domain, this, method, out_args);
+}
+
 static MonoBoolean
 ves_icall_IsTransparentProxy (MonoObject *proxy)
 {
index bb928b9f62434ac9f70f3bc9c3558b31ea641ca1..464b417ef89819992a0b095a24a4352e905ed97e 100644 (file)
@@ -383,5 +383,11 @@ MonoArray  *mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelp
 
 MonoArray  *mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig);
 
+void
+mono_message_init (MonoDomain *domain,
+                  MonoMethodMessage *this, 
+                  MonoReflectionMethod *method,
+                  MonoArray *out_args);
+
 #endif /* __METADATA_REFLECTION_H__ */
 
index 38f73d3dbd9a01cb676d7f7e128e6b7e86138c90..d4baa668e1b724779c29206db5150825e32631e6 100644 (file)
@@ -66,6 +66,8 @@ public struct MyStruct {
        
 class R1 : MarshalByRefObject {
 
+       public int test_field = 5;
+       
        public virtual MyStruct Add (int a, out int c, int b) {
                Console.WriteLine ("ADD");
                c = a + b;
@@ -138,6 +140,12 @@ class Test {
                
                lres = test_call (o);
 
+               //o.test_field = 2;
+               
+               Console.WriteLine ("test_field: " + o.test_field);
+               if (o.test_field != 5)
+                       return 1;
+
                return 0;
        }
 }