+#include <mono/metadata/appdomain.h>
+#if HAVE_BOEHM_GC
+#include <gc/gc.h>
+#endif
+
+void
+mono_runtime_object_init (MonoObject *this)
+{
+ int i;
+ MonoMethod *method = NULL;
+ MonoClass *klass = this->vtable->klass;
+
+ for (i = 0; i < klass->method.count; ++i) {
+ if (!strcmp (".ctor", klass->methods [i]->name) &&
+ klass->methods [i]->signature->param_count == 0) {
+ method = klass->methods [i];
+ break;
+ }
+ }
+
+ g_assert (method);
+
+ mono_runtime_invoke (method, this, NULL);
+}
+
+/*
+ * runtime_class_init:
+ * @klass: klass that needs to be initialized
+ *
+ * This routine calls the class constructor for @class.
+ */
+void
+mono_runtime_class_init (MonoClass *klass)
+{
+ int i;
+
+ for (i = 0; i < klass->method.count; ++i) {
+ MonoMethod *method = klass->methods [i];
+ if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) &&
+ (strcmp (".cctor", method->name) == 0)) {
+ mono_runtime_invoke (method, NULL, NULL);
+ return;
+ }
+ }
+ /* No class constructor found */
+
+}
+
+static MonoInvokeFunc default_mono_runtime_invoke = NULL;
+
+MonoObject*
+mono_runtime_invoke (MonoMethod *method, void *obj, void **params)
+{
+ if (!default_mono_runtime_invoke) {
+ g_error ("runtime invoke called on uninitialized runtime");
+ return NULL;
+ }
+ return default_mono_runtime_invoke (method, obj, params);
+}
+
+int
+mono_runtime_exec_main (MonoMethod *method, MonoArray *args)
+{
+ gpointer pa [1];
+
+ pa [0] = args;
+
+ if (method->signature->ret->type == MONO_TYPE_I4) {
+ MonoObject *res;
+ res = mono_runtime_invoke (method, NULL, pa);
+ return *(guint32 *)((char *)res + sizeof (MonoObject));
+ } else {
+ mono_runtime_invoke (method, NULL, pa);
+ return 0;
+ }
+}
+
+void
+mono_install_runtime_invoke (MonoInvokeFunc func)
+{
+ default_mono_runtime_invoke = func;
+}
+
+MonoObject*
+mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params)
+{
+ MonoMethodSignature *sig = method->signature;
+ gpointer *pa;
+ int i;
+
+ pa = alloca (sizeof (gpointer) * params->bounds->length);
+
+ for (i = 0; i < params->bounds->length; i++) {
+ if (sig->params [i]->byref) {
+ /* nothing to do */
+ }
+
+ switch (sig->params [i]->type) {
+ 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_U8:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_VALUETYPE:
+ pa [i] = (char *)(((gpointer *)params->vector)[i]) + sizeof (MonoObject);
+ break;
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_CLASS:
+ pa [i] = (char *)(((gpointer *)params->vector)[i]);
+ break;
+ default:
+ g_error ("type 0x%x not handled in ves_icall_InternalInvoke", sig->params [i]->type);
+ }
+ }
+
+ if (!strcmp (method->name, ".ctor")) {
+ obj = mono_object_new (mono_domain_get (), method->klass);
+ mono_runtime_invoke (method, obj, pa);
+ return obj;
+ } else
+ return mono_runtime_invoke (method, obj, pa);
+}