#include <mono/metadata/gc-internal.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-counters.h>
+#include "cominterop.h"
#ifdef HAVE_BOEHM_GC
#define NEED_TO_ZERO_PTRFREE 1
/* Main thread */
static MonoThread *main_thread;
+/* Functions supplied by the runtime */
+static MonoRuntimeCallbacks callbacks;
+
/**
* mono_thread_set_main:
* @thread: thread to set as the main thread
#error "MONO_IMT_SIZE cannot be larger than 32"
#endif
+void
+mono_install_callbacks (MonoRuntimeCallbacks *cbs)
+{
+ memcpy (&callbacks, cbs, sizeof (*cbs));
+}
+
+MonoRuntimeCallbacks*
+mono_get_runtime_callbacks (void)
+{
+ return &callbacks;
+}
+
void
mono_install_trampoline (MonoTrampoline func)
{
}
if (ARCH_USE_IMT) {
- vtable_size = sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ vtable_size = MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
if (class->interface_offsets_count) {
imt_table_bytes = sizeof (gpointer) * (MONO_IMT_SIZE);
vtable_size += sizeof (gpointer) * (MONO_IMT_SIZE);
}
} else {
vtable_size = sizeof (gpointer) * (class->max_interface_id + 1) +
- sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
}
mono_stats.used_class_count++;
/* this is a bounded memory retention issue: may want to
* handle it differently when we'll have a rcu-like system.
*/
- runtime_info = mono_image_alloc0 (class->image, sizeof (MonoClassRuntimeInfo) + new_size * sizeof (gpointer));
+ runtime_info = mono_image_alloc0 (class->image, MONO_SIZEOF_CLASS_RUNTIME_INFO + new_size * sizeof (gpointer));
runtime_info->max_domain = new_size - 1;
/* copy the stuff from the older info */
if (old_info) {
mono_stats.imt_number_of_tables++;
mono_stats.imt_tables_size += (sizeof (gpointer) * MONO_IMT_SIZE);
vtsize = sizeof (gpointer) * (MONO_IMT_SIZE) +
- sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
} else {
vtsize = sizeof (gpointer) * (max_interface_id + 1) +
- sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
}
mono_stats.class_vtable_size += vtsize + extra_interface_vtsize;
pvt = (MonoVTable*) (interface_offsets + MONO_IMT_SIZE);
else
pvt = (MonoVTable*) (interface_offsets + max_interface_id + 1);
- memcpy (pvt, vt, sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer));
+ memcpy (pvt, vt, MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer));
pvt->klass = mono_defaults.transparent_proxy_class;
/* we need to keep the GC descriptor for a transparent proxy or we confuse the precise GC */
key = mp_key;
if (proxy_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*));
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*));
rc->interface_count = 1;
rc->interfaces [0] = proxy_class;
rc->proxy_class = mono_defaults.marshalbyrefobject_class;
} else {
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass));
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS);
rc->interface_count = 0;
rc->proxy_class = proxy_class;
}
if (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
int i,j;
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*) * (remote_class->interface_count + 1));
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * (remote_class->interface_count + 1));
rc->proxy_class = remote_class->proxy_class;
rc->interface_count = remote_class->interface_count + 1;
rc->interfaces [j] = extra_class;
} else {
// Replace the old class. The interface array is the same
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*) * remote_class->interface_count);
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * remote_class->interface_count);
rc->proxy_class = extra_class;
rc->interface_count = remote_class->interface_count;
if (rc->interface_count > 0)
/* generic methods demand invoke_with_check */
if (mono_method_signature (res)->generic_param_count)
res = mono_marshal_get_remoting_invoke_with_check (res);
- else
- res = mono_marshal_get_remoting_invoke (res);
+ else {
+#ifndef DISABLE_COM
+ if (klass == mono_defaults.com_object_class || klass->is_com_object)
+ res = mono_cominterop_get_invoke (res);
+ else
+#endif
+ res = mono_marshal_get_remoting_invoke (res);
+ }
} else {
if (method->is_inflated) {
/* Have to inflate the result */
{
int t;
if (type->byref) {
+ /* object fields cannot be byref, so we don't need a
+ wbarrier here */
gpointer *p = (gpointer*)dest;
*p = value;
return;
t = mono_class_enum_basetype (type->data.klass)->type;
goto handle_enum;
} else {
- int size;
- size = mono_class_value_size (mono_class_from_mono_type (type), NULL);
- if (value == NULL)
+ MonoClass *class = mono_class_from_mono_type (type);
+ int size = mono_class_value_size (class, NULL);
+ if (value == NULL) {
memset (dest, 0, size);
- else
+ } else {
memcpy (dest, value, size);
+ mono_gc_wbarrier_value_copy (dest, value, size, class);
+ }
}
return;
case MONO_TYPE_GENERICINST:
else
t = &t->data.generic_class->container_class->byval_arg;
goto again;
+ case MONO_TYPE_PTR: {
+ MonoObject *arg;
+
+ /* The argument should be an IntPtr */
+ arg = mono_array_get (params, MonoObject*, i);
+ if (arg == NULL) {
+ pa [i] = NULL;
+ } else {
+ g_assert (arg->vtable->klass == mono_defaults.int_class);
+ pa [i] = ((MonoIntPtr*)arg)->m_value;
+ }
+ break;
+ }
default:
- g_error ("type 0x%x not handled in ves_icall_InternalInvoke", sig->params [i]->type);
+ g_error ("type 0x%x not handled in mono_runtime_invoke_array", sig->params [i]->type);
}
}
}
/* obj must be already unboxed if needed */
res = mono_runtime_invoke (method, obj, pa, exc);
+ if (sig->ret->type == MONO_TYPE_PTR) {
+ MonoClass *pointer_class;
+ static MonoMethod *box_method;
+ void *box_args [2];
+ MonoObject *box_exc;
+
+ /*
+ * The runtime-invoke wrapper returns a boxed IntPtr, need to
+ * convert it to a Pointer object.
+ */
+ pointer_class = mono_class_from_name_cached (mono_defaults.corlib, "System.Reflection", "Pointer");
+ if (!box_method)
+ box_method = mono_class_get_method_from_name (pointer_class, "Box", -1);
+
+ g_assert (res->vtable->klass == mono_defaults.int_class);
+ box_args [0] = ((MonoIntPtr*)res)->m_value;
+ box_args [1] = mono_type_get_object (mono_domain_get (), sig->ret);
+ res = mono_runtime_invoke (box_method, NULL, box_args, &box_exc);
+ g_assert (!box_exc);
+ }
+
if (has_byref_nullables) {
/*
* The runtime invoke wrapper already converted byref nullables back,
* will point into the next function in the executable, not this one.
*/
- if (((MonoObject*)ex)->vtable->klass == mono_defaults.threadabortexception_class)
- MONO_OBJECT_SETREF (mono_thread_current (), abort_exc, ex);
+ if (((MonoObject*)ex)->vtable->klass == mono_defaults.threadabortexception_class) {
+ MonoThread *thread = mono_thread_current ();
+ g_assert (ex->object.vtable->domain == mono_domain_get ());
+ MONO_OBJECT_SETREF (thread, abort_exc, ex);
+ }
ex_handler (ex);
}
* mono_create_ftnptr:
*
* Given a function address, create a function descriptor for it.
- * This is only needed on IA64 and PPC64.
+ * This is only needed on some platforms.
*/
gpointer
mono_create_ftnptr (MonoDomain *domain, gpointer addr)
{
-#ifdef __ia64__
- gpointer *desc;
-
- desc = mono_domain_code_reserve (domain, 2 * sizeof (gpointer));
-
- desc [0] = addr;
- desc [1] = NULL;
-
- return desc;
-#elif defined(__ppc64__) || defined(__powerpc64__)
- gpointer *desc;
-
- desc = mono_domain_code_reserve (domain, 3 * sizeof (gpointer));
-
- desc [0] = addr;
- desc [1] = NULL;
- desc [2] = NULL;
-
- return desc;
-#else
- return addr;
-#endif
+ return callbacks.create_ftnptr (domain, addr);
}
/*
* mono_get_addr_from_ftnptr:
*
* Given a pointer to a function descriptor, return the function address.
- * This is only needed on IA64 and PPC64.
+ * This is only needed on some platforms.
*/
gpointer
mono_get_addr_from_ftnptr (gpointer descr)
{
-#if defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__)
- return *(gpointer*)descr;
-#else
- return descr;
-#endif
+ return callbacks.get_addr_from_ftnptr (descr);
}
#if 0