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>
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;
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
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 */
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;
+}
#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;
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);
MonoMethod *m;
MethodCallInfo *ci;
MonoClass *klass;
+ MonoClassField *field;
X86AddressInfo ainfo;
} data;
};
%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
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);
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.
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);
}
}
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++;
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;
}
arg_type = 2;
if (sig->params [i]->attrs & PARAM_ATTRIBUTE_IN)
- arg_type = 1;
+ arg_type |= 1;
} else {
arg_type = 1;
}
}
}
+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)
{
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__ */
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;
lres = test_call (o);
+ //o.test_field = 2;
+
+ Console.WriteLine ("test_field: " + o.test_field);
+ if (o.test_field != 5)
+ return 1;
+
return 0;
}
}