#include <mono/metadata/tokentype.h>
#include <mono/metadata/loader.h>
#include <mono/metadata/threads.h>
-#include <mono/metadata/threadpool-ms.h>
+#include <mono/metadata/threadpool.h>
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/reflection.h>
#include "interp.h"
#include "mintops.h"
-#include "embed.h"
#include "hacks.h"
-#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
- a = i,
-
-enum {
-#include "mono/cil/opcode.def"
- CEE_LASTOP
-};
-#undef OPDEF
-
-// TODO: should come from mono/mini/mini.h
-#if 1
- /*
- * Information about a trampoline function.
- */
- typedef struct
- {
- /*
- * The native code of the trampoline. Not owned by this structure.
- */
- guint8 *code;
- guint32 code_size;
- /*
- * The name of the trampoline which can be used in AOT/xdebug. Owned by this
- * structure.
- */
- char *name;
- /*
- * Patches required by the trampoline when aot-ing. Owned by this structure.
- */
- gpointer *ji;
- /*
- * Unwind information. Owned by this structure.
- */
- GSList *unwind_ops;
-
- /*
- * Encoded unwind info loaded from AOT images
- */
- guint8 *uw_info;
- guint32 uw_info_len;
-} MonoTrampInfo;
-gpointer mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info);
-void mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain);
-#else
#include <mono/mini/mini.h>
-#endif
/* Mingw 2.1 doesnt need this any more, but leave it in for now for older versions */
#endif
#endif
-static gint *abort_requested;
-
-/* If true, then we output the opcodes as we interpret them */
-static int global_tracing = 1;
-static int global_no_pointers = 0;
-
int mono_interp_traceopt = 0;
-static int debug_indent_level = 0;
-
#define INIT_FRAME(frame,parent_frame,obj_this,method_args,method_retval,domain,mono_method,error) \
do { \
(frame)->parent = (parent_frame); \
#define DEBUG_INTERP 0
#define COUNT_OPS 0
#if DEBUG_INTERP
+/* If true, then we output the opcodes as we interpret them */
+static int global_tracing = 1;
+
+static int debug_indent_level = 0;
static int break_on_method = 0;
static int nested_trace = 0;
THROW_EX (mono_get_exception_execution_engine (NULL), ip); \
} while (0);
-static gpointer
-interp_create_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target, MonoError *error)
-{
- g_error ("FIXME: use domain and error");
- // return mono_interp_get_runtime_method (mono_marshal_get_remoting_invoke_for_target (method, target));
-}
-
static mono_mutex_t runtime_method_lookup_section;
RuntimeMethod*
if ((m->flags & METHOD_ATTRIBUTE_FINAL) || !(m->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
RuntimeMethod *ret = NULL;
- if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
+ if (mono_object_is_transparent_proxy (obj)) {
ret = mono_interp_get_runtime_method (domain, mono_marshal_get_remoting_invoke (m), &error);
- else if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+ } else if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) {
ret = mono_interp_get_runtime_method (domain, mono_marshal_get_synchronized_wrapper (m), &error);
- else
+ mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+ } else {
ret = runtime_method;
- mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+ }
return ret;
}
- if (m->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
- // return ((RuntimeMethod **)obj->vtable->interface_offsets [m->klass->interface_id]) [m->slot];
- g_error ("FIXME: interface method lookup");
- return NULL;
- } else {
- return ((RuntimeMethod **)obj->vtable->vtable) [m->slot];
+ int slot = mono_method_get_vtable_slot (m);
+ if (mono_class_is_interface (m->klass)) {
+ g_assert (obj->vtable->klass != m->klass);
+ /* TODO: interface offset lookup is slow, go through IMT instead */
+ slot += mono_class_interface_offset (obj->vtable->klass, m->klass);
}
+ MonoMethod *virtual_method = obj->vtable->klass->vtable [slot];
+ RuntimeMethod *virtual_runtime_method = mono_interp_get_runtime_method (domain, virtual_method, &error);
+ mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+ return virtual_runtime_method;
}
static void inline
return;
}
-#if 0 /* FIX */
- if (sp [ac->rank].data.p && !mono_object_isinst (sp [ac->rank].data.p, mono_object_class (o)->element_class)) {
- frame->ex = mono_get_exception_array_type_mismatch ();
- FILL_IN_TRACE (frame->ex, frame);
- return;
+ if (sp [ac->rank].data.p && !mono_object_class (o)->element_class->valuetype) {
+ MonoError error;
+ MonoObject *isinst = mono_object_isinst_checked (sp [ac->rank].data.p, mono_object_class (o)->element_class, &error);
+ mono_error_cleanup (&error);
+ if (!isinst) {
+ frame->ex = mono_get_exception_array_type_mismatch ();
+ FILL_IN_TRACE (frame->ex, frame);
+ return;
+ }
}
-#endif
esize = mono_array_element_size (ac);
ea = mono_array_addr_with_size (ao, esize, pos);
gpointer *iargs;
size_t flen;
gpointer *fargs;
- // TODO: ret val?
+ gpointer *retval;
};
typedef struct _MethodArguments MethodArguments;
if (margs->ilen > 0)
margs->iargs = g_malloc0 (sizeof (gpointer) * margs->ilen);
+ if (margs->ilen > 3)
+ g_error ("build_args_from_sig: TODO, more than two iregs: %d\n", margs->ilen);
+
if (margs->flen > 0)
- g_error ("build_args_from_sig: TODO, allocate floats\n");
+ g_error ("build_args_from_sig: TODO, allocate floats: %d\n", margs->flen);
+
size_t int_i = 0;
- size_t int_f = 0;
if (sig->hasthis) {
margs->iargs [0] = frame->obj;
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_I8:
- margs->iargs [int_i] = frame->stack_args [i].data.l;
+ margs->iargs [int_i] = frame->stack_args [i].data.p;
+#if DEBUG_INTERP
g_printerr ("build_args_from_sig: margs->iargs[%d]: %p (frame @ %d)\n", int_i, margs->iargs[int_i], i);
+#endif
int_i++;
break;
default:
}
}
+ if (sig->ret->type != MONO_TYPE_VOID) {
+ margs->retval = &(frame->retval->data.p);
+ } else {
+ margs->retval = NULL;
+ }
+
return margs;
}
ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFuncV addr, gboolean string_ctor, ThreadContext *context)
{
jmp_buf env;
- MonoPIFunc func;
MonoInvocation *old_frame = context->current_frame;
MonoInvocation *old_env_frame = context->env_frame;
jmp_buf *old_env = context->current_env;
context->env_frame = frame;
context->current_env = &env;
- g_assert (frame->runtime_method);
- func = frame->runtime_method->func;
- if (!func) {
- g_printerr ("ICALL(1): func = NULL, addr = %p\n", addr);
- if (!mono_interp_enter_icall_trampoline) {
- MonoTrampInfo *info;
- mono_interp_enter_icall_trampoline = mono_arch_get_enter_icall_trampoline (&info);
- // mono_tramp_info_register (info, NULL);
- }
- func = mono_interp_enter_icall_trampoline;
- g_printerr ("ICALL(2): func = %p, addr = %p\n", func, addr);
+ g_assert (!frame->runtime_method);
+ if (!mono_interp_enter_icall_trampoline) {
+ MonoTrampInfo *info;
+ mono_interp_enter_icall_trampoline = mono_arch_get_enter_icall_trampoline (&info);
+ // TODO:
+ // mono_tramp_info_register (info, NULL);
}
-
+
MethodArguments *margs = build_args_from_sig (sig, frame);
+#if DEBUG_INTERP
+ g_printerr ("ICALL: mono_interp_enter_icall_trampoline = %p, addr = %p\n", mono_interp_enter_icall_trampoline, addr);
+ g_printerr ("margs(out): ilen=%d, flen=%d\n", margs->ilen, margs->flen);
+#endif
context->current_frame = frame;
context->managed_code = 0;
- g_assert (func);
- func (addr, margs);
+ mono_interp_enter_icall_trampoline (addr, margs);
context->managed_code = 1;
/* domain can only be changed by native code */
context->domain = mono_domain_get ();
- if (*abort_requested)
+ if (*mono_thread_interruption_request_flag ())
mono_thread_interruption_checkpoint ();
-#if 0
- if (string_ctor) {
- stackval_from_data (&mono_defaults.string_class->byval_arg, frame->retval, (char*)&frame->retval->data.p, sig->pinvoke);
- } else if (!MONO_TYPE_ISSTRUCT (sig->ret))
+ if (!MONO_TYPE_ISSTRUCT (sig->ret))
stackval_from_data (sig->ret, frame->retval, (char*)&frame->retval->data.p, sig->pinvoke);
-#endif
context->current_frame = old_frame;
context->env_frame = old_env_frame;
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
delegate->target = target;
- if (target && target->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (target && mono_object_is_transparent_proxy (target)) {
MonoMethod *method = mono_marshal_get_remoting_invoke (runtime_method->method);
delegate->method_ptr = mono_interp_get_runtime_method (domain, method, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
#define CHECK_MUL_OVERFLOW_NAT_UN(a,b) CHECK_MUL_OVERFLOW64_UN(a,b)
#endif
-static MonoObject*
+MonoObject*
interp_mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error)
{
MonoInvocation frame;
}
}
- if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+ if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
method = mono_marshal_get_native_wrapper (method, FALSE, FALSE);
INIT_FRAME(&frame,context->current_frame,obj,args,&result,mono_get_root_domain (),method,error);
if (exc)
func ();
break;
}
+ case MINT_ICALL_V_P: {
+ gpointer (*func)() = ptr;
+ sp++;
+ sp [-1].data.p = func ();
+ break;
+ }
case MINT_ICALL_P_V: {
void (*func)(gpointer) = ptr;
func (sp [-1].data.p);
static GHashTable *method_pointer_hash = NULL;
gpointer
-mono_create_method_pointer (MonoMethod *method, MonoError *error)
+interp_create_method_pointer (MonoMethod *method, MonoError *error)
{
gpointer addr;
MonoJitInfo *ji;
- mono_error_init (error);
mono_os_mutex_lock (&create_method_pointer_mutex);
if (!method_pointer_hash) {
} else {
child_frame.obj = NULL;
}
- if (csignature->hasthis && ((MonoObject *)child_frame.obj)->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (csignature->hasthis && mono_object_is_transparent_proxy (child_frame.obj)) {
child_frame.runtime_method = mono_interp_get_runtime_method (context->domain, mono_marshal_get_remoting_invoke (child_frame.runtime_method->method), &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
} else if (child_frame.runtime_method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
} else {
child_frame.obj = NULL;
}
- if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && ((MonoObject *)child_frame.obj)->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && mono_object_is_transparent_proxy (child_frame.obj)) {
child_frame.runtime_method = mono_interp_get_runtime_method (context->domain, mono_marshal_get_remoting_invoke (child_frame.runtime_method->method), &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
}
child_frame.obj = NULL;
}
- if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && ((MonoObject *)child_frame.obj)->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && mono_object_is_transparent_proxy (child_frame.obj)) {
child_frame.runtime_method = mono_interp_get_runtime_method (context->domain, mono_marshal_get_remoting_invoke (child_frame.runtime_method->method), &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
}
}
MINT_IN_BREAK;
}
- MINT_IN_CASE(MINT_CALLINT)
- g_printerr ("doing MINT_CALLINT: %p\n", ((MonoMethodPInvoke*) frame->runtime_method->method)->addr);
- ves_pinvoke_method (frame, mono_method_signature (frame->runtime_method->method), ((MonoMethodPInvoke*) frame->runtime_method->method)->addr,
- frame->runtime_method->method->string_ctor, context);
- if (frame->ex) {
- rtm = NULL;
- goto handle_exception;
- }
- goto exit_frame;
MINT_IN_CASE(MINT_CALLRUN)
ves_runtime_method (frame, context);
if (frame->ex) {
o = mono_object_new_checked (context->domain, newobj_class, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
context->managed_code = 1;
- if (*abort_requested)
+ if (*mono_thread_interruption_request_flag ())
mono_thread_interruption_checkpoint ();
child_frame.obj = o;
} else {
MINT_IN_CASE(MINT_CASTCLASS)
c = rtm->data_items [*(guint16 *)(ip + 1)];
if ((o = sp [-1].data.p)) {
- if (c->marshalbyref) {
- MonoObject *isinst_obj = mono_object_isinst_mbyref_checked (o, c, &error);
- mono_error_cleanup (&error); /* FIXME: don't swallow the error */
- if (!isinst_obj)
- THROW_EX (mono_get_exception_invalid_cast (), ip);
- } else {
- MonoVTable *vt = o->vtable;
- MonoClass *oklass = vt->klass;
- if (c->flags & TYPE_ATTRIBUTE_INTERFACE) {
- g_error ("FIXME: interface method lookup");
- if (c->interface_id > vt->max_interface_id /* || vt->interface_offsets [c->interface_id] == 0 */) {
- THROW_EX (mono_get_exception_invalid_cast (), ip);
- }
- } else if (c->rank) {
- MonoObject *isinst_obj = mono_object_isinst_checked (o, c, &error);
- mono_error_cleanup (&error); /* FIXME: don't swallow the error */
- if (!isinst_obj)
- THROW_EX (mono_get_exception_invalid_cast (), ip);
- } else if (!mono_class_has_parent (oklass, c)) {
- THROW_EX (mono_get_exception_invalid_cast (), ip);
- }
- }
+ MonoObject *isinst_obj = mono_object_isinst_checked (o, c, &error);
+ mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+ if (!isinst_obj)
+ THROW_EX (mono_get_exception_invalid_cast (), ip);
}
ip += 2;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_ISINST)
c = rtm->data_items [*(guint16 *)(ip + 1)];
if ((o = sp [-1].data.p)) {
- if (c->marshalbyref) {
- MonoObject *isinst_obj = mono_object_isinst_mbyref_checked (o, c, &error);
- mono_error_cleanup (&error); /* FIXME: don't swallow the error */
- if (!isinst_obj)
- sp [-1].data.p = NULL;
- } else {
- MonoVTable *vt = o->vtable;
- MonoClass *oklass = vt->klass;
- if (c->flags & TYPE_ATTRIBUTE_INTERFACE) {
- g_error ("FIXME: interface method lookup");
- if (c->interface_id > vt->max_interface_id /* || vt->interface_offsets [c->interface_id] == 0 */) {
- sp [-1].data.p = NULL;
- }
- } else if (c->rank) {
- MonoObject *isinst_obj = mono_object_isinst_checked (o, c, &error);
- mono_error_cleanup (&error); /* FIXME: don't swallow the error */
- if (!isinst_obj)
- sp [-1].data.p = NULL;
- } else if (!mono_class_has_parent (oklass, c)) {
- sp [-1].data.p = NULL;
- }
- }
+ MonoObject *isinst_obj = mono_object_isinst_checked (o, c, &error);
+ mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+ if (!isinst_obj)
+ sp [-1].data.p = NULL;
}
ip += 2;
MINT_IN_BREAK;
o = sp [-1].data.p;
if (!o)
- THROW_EX (mono_get_exception_null_reference(), ip);
+ THROW_EX (mono_get_exception_null_reference (), ip);
MonoObject *isinst_obj = mono_object_isinst_checked (o, c, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
- if (!(isinst_obj ||
- ((o->vtable->klass->rank == 0) &&
- (o->vtable->klass->element_class == c->element_class))))
+ if (!(isinst_obj || ((o->vtable->klass->rank == 0) && (o->vtable->klass->element_class == c->element_class))))
THROW_EX (mono_get_exception_invalid_cast (), ip);
- sp [-1].data.p = (char *)o + sizeof (MonoObject);
+ if (c->byval_arg.type == MONO_TYPE_VALUETYPE && !c->enumtype) {
+ g_error ("unbox: implement vt");
+ } else {
+ stackval_from_data (&c->byval_arg, &sp [-1], mono_object_unbox (o), FALSE);
+ }
ip += 2;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_THROW)
THROW_EX (mono_get_exception_null_reference (), ip);
field = rtm->data_items[* (guint16 *)(ip + 1)];
ip += 2;
- if (o->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (mono_object_is_transparent_proxy (o)) {
MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class;
addr = mono_load_remote_field_checked (o, klass, field, &tmp, &error);
field = rtm->data_items[* (guint16 *)(ip + 1)];
i32 = READ32(ip + 2);
ip += 4;
- if (o->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (mono_object_is_transparent_proxy (o)) {
MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class;
addr = mono_load_remote_field_checked (o, klass, field, &tmp, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
field = rtm->data_items[* (guint16 *)(ip + 1)];
ip += 2;
- if (o->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (mono_object_is_transparent_proxy (o)) {
MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class;
mono_store_remote_field_checked (o, klass, field, &sp [-1].data, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
i32 = READ32(ip + 2);
ip += 4;
- if (o->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (mono_object_is_transparent_proxy (o)) {
MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class;
mono_store_remote_field_checked (o, klass, field, &sp [-1].data, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
goto handle_finally;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_ICALL_V_V)
+ MINT_IN_CASE(MINT_ICALL_V_P)
MINT_IN_CASE(MINT_ICALL_P_V)
MINT_IN_CASE(MINT_ICALL_P_P)
MINT_IN_CASE(MINT_ICALL_PP_V)
g_error ("No entry point method found in %s", mono_image_get_filename (image));
rval = mono_runtime_run_main_checked (method, argc, argv, &error);
- return_val_and_set_pending_if_nok (&error, rval);
+ mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+ return rval;
}
static void
exit (1);
}
-static void
-add_signal_handler (int signo, void (*handler)(int))
-{
-#ifdef HOST_WIN32
- signal (signo, handler);
-#else
- struct sigaction sa;
-
- sa.sa_handler = handler;
- sigemptyset (&sa.sa_mask);
- sa.sa_flags = 0;
-
- g_assert (sigaction (signo, &sa, NULL) != -1);
-#endif
-}
-
-static void
-segv_handler (int signum)
-{
- ThreadContext *context = mono_native_tls_get_value (thread_context_id);
- MonoException *segv_exception;
-
- if (context == NULL)
- return;
- segv_exception = mono_get_exception_null_reference ();
- segv_exception->message = mono_string_new (mono_domain_get (), "Null Reference (SIGSEGV)");
- mono_raise_exception (segv_exception);
-}
-
-
-static void
-quit_handler (int signum)
-{
- ThreadContext *context = mono_native_tls_get_value (thread_context_id);
- MonoException *quit_exception;
-
- if (context == NULL)
- return;
- quit_exception = mono_get_exception_execution_engine ("Interrupted (SIGQUIT).");
- mono_raise_exception (quit_exception);
-}
-
-static void
-abrt_handler (int signum)
-{
- ThreadContext *context = mono_native_tls_get_value (thread_context_id);
- MonoException *abrt_exception;
-
- if (context == NULL)
- return;
- abrt_exception = mono_get_exception_execution_engine ("Abort (SIGABRT).");
- mono_raise_exception (abrt_exception);
-}
-
-#if 0
-static void
-thread_abort_handler (int signum)
-{
- ThreadContext *context = mono_native_tls_get_value (thread_context_id);
- MonoException *exc;
-
- if (context == NULL)
- return;
-
- exc = mono_thread_request_interruption (context->managed_code);
- if (exc) mono_raise_exception (exc);
-}
-#endif
-
static MonoBoolean
-ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
+interp_ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
MonoReflectionMethod **method,
gint32 *iloffset, gint32 *native_offset,
MonoString **file, gint32 *line, gint32 *column)
}
static MonoArray *
-ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
+interp_ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
{
MonoDomain *domain = mono_domain_get ();
MonoArray *res;
return delegate;
}
-
-typedef struct
-{
- MonoDomain *domain;
- int enable_debugging;
- char *file;
- int argc;
- char **argv;
-} MainThreadArgs;
-
-static void main_thread_handler (gpointer user_data)
-{
- MainThreadArgs *main_args=(MainThreadArgs *)user_data;
- MonoAssembly *assembly;
-
- if (main_args->enable_debugging) {
- mono_debug_init (MONO_DEBUG_FORMAT_MONO);
- }
-
- assembly = mono_domain_assembly_open (main_args->domain, main_args->file);
-
- if (!assembly){
- fprintf (stderr, "Can not open image %s\n", main_args->file);
- exit (1);
- }
-
- ves_exec (main_args->domain, assembly, main_args->argc, main_args->argv);
-}
-
-static void
-mono_runtime_install_handlers (void)
-{
- add_signal_handler (SIGSEGV, segv_handler);
- add_signal_handler (SIGINT, quit_handler);
- add_signal_handler (SIGABRT, abrt_handler);
-#if 0
- add_signal_handler (mono_thread_get_abort_signal (), thread_abort_handler);
-#endif
-}
-
-static void
-quit_function (MonoDomain *domain, gpointer user_data)
-{
- mono_profiler_shutdown ();
-
- mono_runtime_cleanup (domain);
- mono_domain_free (domain, TRUE);
-
-}
-
void
-mono_interp_cleanup(MonoDomain *domain)
-{
- quit_function (domain, NULL);
-}
-
-int
-mono_interp_exec(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[])
-{
- return ves_exec (domain, assembly, argc, argv);
-}
-
-gpointer*
-interp_get_imt_trampoline (MonoVTable *vtable, int imt_slot_index)
-{
- // FIXME: implement me
- return NULL;
-}
-
-static gpointer
-interp_create_ftnptr (MonoDomain *domain, gpointer addr)
-{
- // FIXME: true on all arch?
- return addr;
-}
-
-MonoDomain *
-mono_interp_init(const char *file)
+mono_interp_init ()
{
- MonoDomain *domain;
- MonoRuntimeCallbacks callbacks;
- MonoRuntimeExceptionHandlingCallbacks ecallbacks;
- MonoError error;
-
- g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
- g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR);
-
mono_native_tls_alloc (&thread_context_id, NULL);
mono_native_tls_set_value (thread_context_id, NULL);
mono_os_mutex_init_recursive (&runtime_method_lookup_section);
mono_os_mutex_init_recursive (&create_method_pointer_mutex);
- // TODO: use callbacks?
- mono_runtime_install_handlers ();
mono_interp_transform_init ();
-
- memset (&callbacks, 0, sizeof (callbacks));
- // TODO: replace with `mono_install_callbacks`
- callbacks.compile_method = mono_create_method_pointer;
- callbacks.runtime_invoke = interp_mono_runtime_invoke;
- callbacks.get_imt_trampoline = interp_get_imt_trampoline;
- callbacks.create_ftnptr = interp_create_ftnptr;
-#ifndef DISABLE_REMOTING
- mono_install_remoting_trampoline (interp_create_remoting_trampoline);
-#endif
- callbacks.create_jit_trampoline = interp_create_trampoline;
- mono_install_callbacks (&callbacks);
-
-
- memset (&ecallbacks, 0, sizeof (ecallbacks));
- ecallbacks.mono_raise_exception = interp_ex_handler;
-#if 0
- // FIXME: ...
- mono_install_stack_walk (interp_walk_stack);
-#endif
- mono_install_eh_callbacks (&ecallbacks);
-
- mono_install_runtime_cleanup (quit_function);
-
- abort_requested = mono_thread_interruption_request_flag ();
-
- domain = mono_init_from_assembly (file, file);
-#ifdef __hpux /* generates very big stack frames */
- mono_threads_set_default_stacksize(32*1024*1024);
-#endif
- mono_icall_init ();
- mono_add_internal_call ("System.Diagnostics.StackFrame::get_frame_info", ves_icall_get_frame_info);
- mono_add_internal_call ("System.Diagnostics.StackTrace::get_trace", ves_icall_get_trace);
- mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers", mono_runtime_install_handlers);
- mono_add_internal_call ("System.Delegate::CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal);
-
- mono_register_jit_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", mono_create_icall_signature ("void"), FALSE);
-
- mono_runtime_init_checked (domain, NULL, NULL, &error);
- mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-
- mono_thread_attach (domain);
- return domain;
}
typedef int (*TestMethod) (void);
interp_regression_step (MonoImage *image, int verbose, int *total_run, int *total, GTimer *timer, MonoDomain *domain)
{
int result, expected, failed, cfailed, run;
- TestMethod func;
- double elapsed, transform_time, start_time;
+ double elapsed, transform_time;
int i;
MonoObject *result_obj;
+ static gboolean filter_method_init = FALSE;
+ static const char *filter_method = NULL;
g_print ("Test run: image=%s\n", mono_image_get_filename (image));
cfailed = failed = run = 0;
mono_error_cleanup (&error); /* FIXME don't swallow the error */
continue;
}
- if (strncmp (method->name, "test_", 5) == 0) {
+
+ if (!filter_method_init) {
+ filter_method = g_getenv ("INTERP_FILTER_METHOD");
+ filter_method_init = TRUE;
+ }
+ gboolean filter = FALSE;
+ if (filter_method) {
+ const char *name = filter_method;
+
+ if ((strchr (name, '.') > name) || strchr (name, ':')) {
+ MonoMethodDesc *desc = mono_method_desc_new (name, TRUE);
+ filter = mono_method_desc_full_match (desc, method);
+ mono_method_desc_free (desc);
+ } else {
+ filter = strcmp (method->name, name) == 0;
+ }
+ } else { // no filter
+ filter = TRUE;
+ }
+ if (strncmp (method->name, "test_", 5) == 0 && filter) {
MonoError interp_error;
- RuntimeMethod *runtime_method;
- MonoInvocation frame;
- ThreadContext context;
- stackval frame_result;
+ MonoObject *exc = NULL;
- result_obj = interp_mono_runtime_invoke (method, NULL, NULL, NULL, &interp_error);
+ result_obj = interp_mono_runtime_invoke (method, NULL, NULL, &exc, &interp_error);
if (!mono_error_ok (&interp_error)) {
cfailed++;
g_print ("Test '%s' execution failed.\n", method->name);
+ } else if (exc != NULL) {
+ g_print ("Exception in Test '%s' occured:\n", method->name);
+ mono_object_describe (exc);
+ run++;
+ failed++;
} else {
result = *(gint32 *) mono_object_unbox (result_obj);
expected = atoi (method->name + 5); // FIXME: oh no.
interp_regression (MonoImage *image, int verbose, int *total_run)
{
MonoMethod *method;
- char *n;
GTimer *timer = g_timer_new ();
MonoDomain *domain = mono_domain_get ();
- guint32 i, exclude = 0;
+ guint32 i;
int total;
/* load the metadata */