#include <mono/metadata/object.h>
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/exception.h>
-#include <mono/metadata/appdomain.h>
+#include <mono/metadata/domain-internals.h>
+#include "mono/metadata/metadata-internals.h"
+#include "mono/metadata/class-internals.h"
#include <mono/metadata/assembly.h>
#include <mono/metadata/threadpool.h>
#include <mono/metadata/marshal.h>
#include "mono/metadata/debug-helpers.h"
#include "mono/metadata/marshal.h"
#include <mono/metadata/threads.h>
+#include <mono/metadata/threads-types.h>
#include <mono/metadata/environment.h>
#include "mono/metadata/profiler-private.h"
#include <mono/os/gc_wrapper.h>
g_assert (method);
+ if (method->klass->valuetype)
+ this = mono_object_unbox (this);
mono_runtime_invoke (method, this, NULL, NULL);
}
/* GC 6.1 has trouble handling 64 bit descriptors... */
if ((class->instance_size / sizeof (gpointer)) > 30) {
-// printf ("TOO LARGE: %s %d.\n", class->name, class->instance_size / sizeof (gpointer));
+/* printf ("TOO LARGE: %s %d.\n", class->name, class->instance_size / sizeof (gpointer)); */
return;
}
count ++;
-// if (count > 442)
-// return;
+/* if (count > 442) */
+/* return; */
-// printf("KLASS: %s.\n", class->name);
+/* printf("KLASS: %s.\n", class->name); */
for (p = class; p != NULL; p = p->parent) {
for (i = 0; i < p->field.count; ++i) {
case MONO_TYPE_U8:
case MONO_TYPE_R4:
case MONO_TYPE_R8:
-// printf ("F: %s %s %d %lld %llx.\n", class->name, field->name, field->offset, ((guint64)1) << pos, bitmap);
+/* printf ("F: %s %s %d %lld %llx.\n", class->name, field->name, field->offset, ((guint64)1) << pos, bitmap); */
break;
case MONO_TYPE_I:
case MONO_TYPE_STRING:
g_assert ((field->offset % sizeof(gpointer)) == 0);
bitmap |= ((guint64)1) << pos;
-// printf ("F: %s %s %d %d %lld %llx.\n", class->name, field->name, field->offset, pos, ((guint64)(1)) << pos, bitmap);
+/* printf ("F: %s %s %d %d %lld %llx.\n", class->name, field->name, field->offset, pos, ((guint64)(1)) << pos, bitmap); */
break;
case MONO_TYPE_VALUETYPE: {
MonoClass *fclass = field->type->data.klass;
}
}
-// printf("CLASS: %s.%s -> %d %llx.\n", class->name_space, class->name, class->instance_size / sizeof (gpointer), bitmap);
+/* printf("CLASS: %s.%s -> %d %llx.\n", class->name_space, class->name, class->instance_size / sizeof (gpointer), bitmap); */
class->gc_bitmap = bitmap;
/* Convert to the format expected by GC_make_descriptor */
bm [0] = (guint32)bitmap;
#if CREATION_SPEEDUP
mono_class_compute_gc_descriptor (class);
- if (domain != mono_root_domain)
+ if (domain != mono_get_root_domain ())
/*
* We can't use typed allocation in the non-root domains, since the
* collector needs the GC descriptor stored in the vtable even after
mono_domain_unlock (domain);
}
-/*
- * Retrieve the MonoMethod that would to be called on obj if obj is passed as
+/**
+ * mono_object_get_virtual_method:
+ *
+ * Retrieve the MonoMethod that would be called on obj if obj is passed as
* the instance of a callvirt of method.
*/
MonoMethod*
static MonoInvokeFunc default_mono_runtime_invoke = dummy_mono_runtime_invoke;
+/**
+ * mono_runtime_invoke:
+ *
+ * Invokes the method represented by `method' on the object `obj'.
+ *
+ * obj is the 'this' pointer, it should be NULL for static
+ * methods, a MonoObject* for object instances and a pointer to
+ * the value type for value types.
+ *
+ * The params array contains the arguments to the method with the
+ * same convention: MonoObject* pointers for object instances and
+ * pointers to the value type otherwise.
+ *
+ * From unmanaged code you'll usually use the
+ * mono_runtime_invoke() variant.
+ *
+ * Note that this function doesn't handle virtual methods for
+ * you, it will exec the exact method you pass: we still need to
+ * expose a function to lookup the derived class implementation
+ * of a virtual method (there are examples of this in the code,
+ * though).
+ *
+ * You can pass NULL as the exc argument if you don't want to
+ * catch exceptions, otherwise, *exc will be set to the exception
+ * thrown, if any. if an exception is thrown, you can't use the
+ * MonoObject* result from the function.
+ *
+ * If the method returns a value type, it is boxed in an object
+ * reference.
+ */
MonoObject*
mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
field = mono_class_get_field_from_name (mono_defaults.appdomain_class, "ProcessExit");
g_assert (field);
- if (domain != mono_root_domain)
+ if (domain != mono_get_root_domain ())
return;
delegate = *(MonoObject **)(((char *)domain->domain) + field->offset);
/* set exitcode only in the main thread */
if (mono_thread_current () == main_thread)
mono_environment_exitcode_set (1);
- if (domain != mono_root_domain || !delegate) {
+ if (domain != mono_get_root_domain () || !delegate) {
mono_print_unhandled_exception (exc);
} else {
MonoObject *e = NULL;
default_mono_runtime_invoke = func ? func: dummy_mono_runtime_invoke;
}
+/**
+ * mono_runtime_invoke:
+ *
+ * Invokes the method represented by `method' on the object `obj'.
+ *
+ * obj is the 'this' pointer, it should be NULL for static
+ * methods, a MonoObject* for object instances and a pointer to
+ * the value type for value types.
+ *
+ * The params array contains the arguments to the method with the
+ * same convention: MonoObject* pointers for object instances and
+ * pointers to the value type otherwise. The _invoke_array
+ * variant takes a C# object[] as the params argument (MonoArray
+ * *params): in this case the value types are boxed inside the
+ * respective reference representation.
+ *
+ * From unmanaged code you'll usually use the
+ * mono_runtime_invoke() variant.
+ *
+ * Note that this function doesn't handle virtual methods for
+ * you, it will exec the exact method you pass: we still need to
+ * expose a function to lookup the derived class implementation
+ * of a virtual method (there are examples of this in the code,
+ * though).
+ *
+ * You can pass NULL as the exc argument if you don't want to
+ * catch exceptions, otherwise, *exc will be set to the exception
+ * thrown, if any. if an exception is thrown, you can't use the
+ * MonoObject* result from the function.
+ *
+ * If the method returns a value type, it is boxed in an object
+ * reference.
+ */
MonoObject*
mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
MonoObject **exc)
}
if (!strcmp (method->name, ".ctor") && method->klass != mono_defaults.string_class) {
+ void *o = obj;
if (!obj) {
obj = mono_object_new (mono_domain_get (), method->klass);
if (mono_object_class(obj) == mono_defaults.transparent_proxy_class) {
method = mono_marshal_get_remoting_invoke (method->slot == -1 ? method : method->klass->vtable [method->slot]);
}
+ if (method->klass->valuetype)
+ o = mono_object_unbox (obj);
+ else
+ o = obj;
}
- mono_runtime_invoke (method, obj, pa, exc);
+ mono_runtime_invoke (method, o, pa, exc);
return obj;
- } else
+ } else {
+ /* obj must be already unboxed if needed */
return mono_runtime_invoke (method, obj, pa, exc);
+ }
}
static void
}
#endif
-/**
- * mono_object_free:
- *
- * Frees the memory used by the object. Debugging purposes
- * only, as we will have our GC system.
- */
-void
-mono_object_free (MonoObject *o)
-{
-#if HAVE_BOEHM_GC
- g_error ("mono_object_free called with boehm gc.");
-#else
- MonoClass *c = o->vtable->klass;
-
- memset (o, 0, c->instance_size);
- free (o);
-#endif
-}
-
/**
* mono_object_new:
* @klass: the class of the object that we want to create
*
- * Returns: A newly created object whose definition is
- * looked up using @klass
+ * Returns a newly created object whose definition is
+ * looked up using @klass. This will not invoke any constructors,
+ * so the consumer of this routine has to invoke any constructors on
+ * its own to initialize the object.
*/
MonoObject *
mono_object_new (MonoDomain *domain, MonoClass *klass)
if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
o = mono_object_allocate_spec (vtable->klass->instance_size, vtable);
} else {
-// printf("OBJECT: %s.%s.\n", vtable->klass->name_space, vtable->klass->name);
+/* printf("OBJECT: %s.%s.\n", vtable->klass->name_space, vtable->klass->name); */
o = mono_object_allocate (vtable->klass->instance_size);
o->vtable = vtable;
}
if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
o = mono_object_allocate_spec (vtable->klass->instance_size, vtable);
} else {
-// printf("OBJECT: %s.%s.\n", vtable->klass->name_space, vtable->klass->name);
+/* printf("OBJECT: %s.%s.\n", vtable->klass->name_space, vtable->klass->name); */
o = mono_object_allocate (vtable->klass->instance_size);
o->vtable = vtable;
}
if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
o = mono_object_allocate_spec (byte_len, vtable);
} else {
-// printf("ARRAY: %s.%s.\n", vtable->klass->name_space, vtable->klass->name);
+/* printf("ARRAY: %s.%s.\n", vtable->klass->name_space, vtable->klass->name); */
o = mono_object_allocate (byte_len);
o->vtable = vtable;
}
return res;
}
+MonoDomain*
+mono_object_get_domain (MonoObject *obj)
+{
+ return mono_object_domain (obj);
+}
+
+MonoClass*
+mono_object_get_class (MonoObject *obj)
+{
+ return mono_object_class (obj);
+}
+
gpointer
mono_object_unbox (MonoObject *obj)
{
/* add assert for valuetypes? */
+ g_assert (obj->vtable->klass->valuetype);
return ((char*)obj) + sizeof (MonoObject);
}
}
}
- return mono_runtime_invoke_array (method, target, msg->args, exc);
+ return mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
}
void