break;
}
case MONO_TYPE_STRING: {
- /*gpointer *val = (gpointer*)t;
- *val = mono_string_new_utf16 (domain, (const guint16*)p, len/2);*/
+ gpointer *val = (gpointer*)t;
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+ gunichar2 *copy = g_malloc (len);
+ int j;
+ for (j = 0; j < len/2; j++) {
+ copy [j] = read16 (p);
+ p += 2;
+ }
+ *val = mono_string_new_utf16 (domain, copy, len/2);
+ g_free (copy);
+#else
+ *val = mono_string_new_utf16 (domain, (const guint16*)p, len/2);
+#endif
break;
}
case MONO_TYPE_CLASS:
return default_mono_runtime_invoke (method, obj, params, exc);
}
+static void
+set_value (MonoType *type, void *dest, void *value) {
+ int t;
+ if (type->byref) {
+ gpointer *p = (gpointer*)dest;
+ *p = value;
+ return;
+ }
+handle_enum:
+ t = type->type;
+ switch (t) {
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1: {
+ guint8 *p = (guint8*)dest;
+ *p = *(guint8*)value;
+ return;
+ }
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR: {
+ guint16 *p = (guint16*)dest;
+ *p = *(guint16*)value;
+ return;
+ }
+#if SIZEOF_VOID_P == 4
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+#endif
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4: {
+ gint32 *p = (gint32*)dest;
+ *p = *(gint32*)value;
+ return;
+ }
+#if SIZEOF_VOID_P == 8
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+#endif
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8: {
+ gint64 *p = (gint64*)dest;
+ *p = *(gint64*)value;
+ return;
+ }
+ case MONO_TYPE_R4: {
+ float *p = (float*)dest;
+ *p = *(float*)value;
+ return;
+ }
+ case MONO_TYPE_R8: {
+ double *p = (double*)dest;
+ *p = *(double*)value;
+ return;
+ }
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_PTR: {
+ gpointer *p = (gpointer*)dest;
+ *p = value;
+ return;
+ }
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype) {
+ t = type->data.klass->enum_basetype->type;
+ goto handle_enum;
+ } else {
+ int size;
+ size = mono_class_value_size (type->data.klass, NULL);
+ memcpy (dest, value, size);
+ }
+ return;
+ default:
+ g_warning ("got type %x", type->type);
+ g_assert_not_reached ();
+ }
+}
+
+void
+mono_field_set_value (MonoObject *obj, MonoClassField *field, void *value)
+{
+ void *dest;
+
+ g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
+
+ dest = (char*)obj + field->offset;
+ set_value (field->type, dest, value);
+}
+
+void
+mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
+{
+ void *dest;
+
+ g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
+
+ dest = (char*)vt->data + field->offset;
+ set_value (field->type, dest, value);
+}
+
+void
+mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
+{
+ void *src;
+
+ g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
+
+ src = (char*)obj + field->offset;
+ set_value (field->type, value, src);
+}
+
+void
+mono_field_static_get_value (MonoVTable *vt, MonoClassField *field, void *value)
+{
+ void *src;
+
+ g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
+
+ src = (char*)vt->data + field->offset;
+ set_value (field->type, value, src);
+}
+
+void
+mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
+{
+ default_mono_runtime_invoke (prop->set, obj, params, exc);
+}
+
+MonoObject*
+mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
+{
+ return default_mono_runtime_invoke (prop->get, obj, params, exc);
+}
+
+
MonoMethod *
mono_get_delegate_invoke (MonoClass *klass)
{
"UnhandledException");
g_assert (field);
- delegate = *(MonoObject **)(((char *)domain->domain) + field->offset);
+ if (exc->vtable->klass != mono_defaults.threadabortexception_class) {
+ delegate = *(MonoObject **)(((char *)domain->domain) + field->offset);
- if (!delegate) {
- mono_print_unhandled_exception (exc);
- } else {
- MonoObject *e = NULL;
- gpointer pa [2];
+ if (!delegate) {
+ mono_print_unhandled_exception (exc);
+ } else {
+ MonoObject *e = NULL;
+ gpointer pa [2];
- /* fixme: pass useful arguments */
- pa [0] = NULL;
- pa [1] = NULL;
- mono_runtime_delegate_invoke (delegate, pa, &e);
-
- if (e)
- g_warning ("exception inside UnhandledException handler!");
+ /* fixme: pass useful arguments */
+ pa [0] = NULL;
+ pa [1] = NULL;
+ mono_runtime_delegate_invoke (delegate, pa, &e);
+
+ if (e)
+ g_warning ("exception inside UnhandledException handler!");
+ }
}
}
if ((ji = mono_jit_info_table_find (domain, addr))) {
method = ji->method;
- delegate->method_info = mono_method_get_object (domain, method);
+ delegate->method_info = mono_method_get_object (domain, method, NULL);
}
if (target && target->vtable->klass == mono_defaults.transparent_proxy_class) {
g_assert (method);
- delegate->method_ptr = arch_create_remoting_trampoline (method);
+ method = mono_marshal_get_remoting_invoke (method);
+ delegate->method_ptr = mono_compile_method (method);
delegate->target = target;
} else {
delegate->method_ptr = addr;
msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
if (invoke) {
- mono_message_init (domain, msg, mono_method_get_object (domain, invoke), NULL);
+ mono_message_init (domain, msg, mono_method_get_object (domain, invoke, NULL), NULL);
count = sig->param_count - 2;
} else {
- mono_message_init (domain, msg, mono_method_get_object (domain, method), NULL);
+ mono_message_init (domain, msg, mono_method_get_object (domain, method, NULL), NULL);
count = sig->param_count;
}
}
}
+/**
+ * mono_load_remote_field:
+ * @this: pointer to an object
+ * @klass: klass of the object containing @field
+ * @field: the field to load
+ * @res: a storage to store the result
+ *
+ * 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.
+ */
+gpointer
+mono_load_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *field, gpointer *res)
+{
+ static MonoMethod *getter = NULL;
+ MonoDomain *domain = mono_domain_get ();
+ MonoClass *field_class;
+ MonoMethodMessage *msg;
+ MonoArray *out_args;
+ MonoObject *exc;
+ gpointer tmp;
+
+ g_assert (this->vtable->klass == mono_defaults.transparent_proxy_class);
+
+ if (!res)
+ res = &tmp;
+
+ 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, NULL), 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));
+
+ mono_remoting_invoke ((MonoObject *)((MonoTransparentProxy *)this)->rp, msg, &exc, &out_args);
+
+ *res = mono_array_get (out_args, MonoObject *, 0);
+
+ if (field_class->valuetype) {
+ return ((char *)*res) + sizeof (MonoObject);
+ } else
+ return res;
+}
+
+/**
+ * mono_store_remote_field:
+ * @this: pointer to an object
+ * @klass: klass of the object containing @field
+ * @field: the field to load
+ * @val: the value/object to store
+ *
+ * This method is called by the runtime on attempts to store fields of
+ * transparent proxy objects. @this points to such TP, @klass is the class of
+ * the object containing @field. @val is the new value to store in @field.
+ */
+void
+mono_store_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *field, gpointer val)
+{
+ static MonoMethod *setter = NULL;
+ MonoDomain *domain = mono_domain_get ();
+ MonoClass *field_class;
+ MonoMethodMessage *msg;
+ MonoArray *out_args;
+ MonoObject *exc;
+ MonoObject *arg;
+
+ g_assert (this->vtable->klass == mono_defaults.transparent_proxy_class);
+
+ if (!setter) {
+ 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, "FieldSetter")) {
+ setter = cm;
+ break;
+ }
+ }
+ g_assert (setter);
+ }
+
+ field_class = mono_class_from_mono_type (field->type);
+
+ if (field_class->valuetype)
+ arg = mono_value_box (domain, field_class, val);
+ else
+ arg = *((MonoObject **)val);
+
+
+ msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
+ mono_message_init (domain, msg, mono_method_get_object (domain, setter, NULL), NULL);
+
+ 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));
+ mono_array_set (msg->args, gpointer, 2, arg);
+
+ mono_remoting_invoke ((MonoObject *)((MonoTransparentProxy *)this)->rp, msg, &exc, &out_args);
+}
+