[interp] remove register keyword hack.
[mono.git] / mono / mini / interp / interp.c
index a86eb609dfc98a524f390c11af3a057e216a7394..05ec88a1dc112bb8c8e9559c82c675c6312c8fe2 100644 (file)
@@ -36,7 +36,7 @@
 
 /* trim excessive headers */
 #include <mono/metadata/image.h>
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/cil-coff.h>
 #include <mono/metadata/mono-endian.h>
 #include <mono/metadata/tabledefs.h>
@@ -253,26 +253,23 @@ ves_real_abort (int line, MonoMethod *mh,
                THROW_EX (mono_get_exception_execution_engine (NULL), ip); \
        } while (0);
 
-static mono_mutex_t runtime_method_lookup_section;
-
 RuntimeMethod*
 mono_interp_get_runtime_method (MonoDomain *domain, MonoMethod *method, MonoError *error)
 {
        RuntimeMethod *rtm;
        error_init (error);
 
-       mono_os_mutex_lock (&runtime_method_lookup_section);
+       mono_domain_jit_code_hash_lock (domain);
        if ((rtm = mono_internal_hash_table_lookup (&domain->jit_code_hash, method))) {
-               mono_os_mutex_unlock (&runtime_method_lookup_section);
+               mono_domain_jit_code_hash_unlock (domain);
                return rtm;
        }
-       rtm = mono_mempool_alloc (domain->mp, sizeof (RuntimeMethod));
-       memset (rtm, 0, sizeof (*rtm));
+       rtm = mono_domain_alloc0 (domain, sizeof (RuntimeMethod));
        rtm->method = method;
        rtm->param_count = mono_method_signature (method)->param_count;
        rtm->hasthis = mono_method_signature (method)->hasthis;
        mono_internal_hash_table_insert (&domain->jit_code_hash, method, rtm);
-       mono_os_mutex_unlock (&runtime_method_lookup_section);
+       mono_domain_jit_code_hash_unlock (domain);
 
        return rtm;
 }
@@ -328,6 +325,11 @@ get_virtual_method (MonoDomain *domain, RuntimeMethod *runtime_method, MonoObjec
                virtual_method = mono_class_inflate_generic_method_checked (virtual_method, &context, &error);
                mono_error_cleanup (&error); /* FIXME: don't swallow the error */
        }
+
+       if (virtual_method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) {
+               virtual_method = mono_marshal_get_synchronized_wrapper (virtual_method);
+       }
+
        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;
@@ -525,7 +527,7 @@ fill_in_trace (MonoException *exception, MonoInvocation *frame)
        } while (0)
 
 static MonoObject*
-ves_array_create (MonoDomain *domain, MonoClass *klass, MonoMethodSignature *sig, stackval *values)
+ves_array_create (MonoInvocation *frame, MonoDomain *domain, MonoClass *klass, MonoMethodSignature *sig, stackval *values)
 {
        uintptr_t *lengths;
        intptr_t *lower_bounds;
@@ -547,46 +549,58 @@ ves_array_create (MonoDomain *domain, MonoClass *klass, MonoMethodSignature *sig
                lengths += klass->rank;
        }
        obj = (MonoObject*) mono_array_new_full_checked (domain, klass, lengths, lower_bounds, &error);
+       if (!mono_error_ok (&error)) {
+               frame->ex = mono_error_convert_to_exception (&error);
+               FILL_IN_TRACE (frame->ex, frame);
+       }
        mono_error_cleanup (&error); /* FIXME: don't swallow the error */
        return obj;
 }
 
-static void 
+static gint32
+ves_array_calculate_index (MonoArray *ao, stackval *sp, MonoInvocation *frame)
+{
+       g_assert (!frame->ex);
+       MonoClass *ac = ((MonoObject *) ao)->vtable->klass;
+
+       guint32 pos = 0;
+       if (ao->bounds) {
+               for (gint32 i = 0; i < ac->rank; i++) {
+                       guint32 idx = sp [i].data.i;
+                       guint32 lower = ao->bounds [i].lower_bound;
+                       guint32 len = ao->bounds [i].length;
+                       if (idx < lower || (idx - lower) >= len) {
+                               frame->ex = mono_get_exception_index_out_of_range ();
+                               FILL_IN_TRACE (frame->ex, frame);
+                               return -1;
+                       }
+                       pos = (pos * len) + idx - lower;
+               }
+       } else {
+               pos = sp [0].data.i;
+               if (pos >= ao->max_length) {
+                       frame->ex = mono_get_exception_index_out_of_range ();
+                       FILL_IN_TRACE (frame->ex, frame);
+                       return -1;
+               }
+       }
+       return pos;
+}
+
+static void
 ves_array_set (MonoInvocation *frame)
 {
        stackval *sp = frame->stack_args + 1;
-       MonoObject *o;
-       MonoArray *ao;
-       MonoClass *ac;
-       gint32 i, t, pos, esize;
-       gpointer ea;
-       MonoType *mt;
 
-       o = frame->stack_args->data.p;
-       ao = (MonoArray *)o;
-       ac = o->vtable->klass;
+       MonoObject *o = frame->stack_args->data.p;
+       MonoArray *ao = (MonoArray *) o;
+       MonoClass *ac = o->vtable->klass;
 
        g_assert (ac->rank >= 1);
 
-       pos = sp [0].data.i;
-       if (ao->bounds != NULL) {
-               pos -= ao->bounds [0].lower_bound;
-               for (i = 1; i < ac->rank; i++) {
-                       if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >= 
-                           ao->bounds [i].length) {
-                               frame->ex = mono_get_exception_index_out_of_range ();
-                               FILL_IN_TRACE(frame->ex, frame);
-                               return;
-                       }
-                       pos = pos*ao->bounds [i].length + sp [i].data.i - 
-                               ao->bounds [i].lower_bound;
-               }
-       } else if (pos >= ao->max_length) {
-               frame->ex = mono_get_exception_index_out_of_range ();
-               FILL_IN_TRACE(frame->ex, frame);
+       gint32 pos = ves_array_calculate_index (ao, sp, frame);
+       if (frame->ex)
                return;
-       }
-
 
        if (sp [ac->rank].data.p && !mono_object_class (o)->element_class->valuetype) {
                MonoError error;
@@ -599,88 +613,52 @@ ves_array_set (MonoInvocation *frame)
                }
        }
 
-       esize = mono_array_element_size (ac);
-       ea = mono_array_addr_with_size (ao, esize, pos);
+       gint32 esize = mono_array_element_size (ac);
+       gpointer ea = mono_array_addr_with_size (ao, esize, pos);
 
-       mt = mono_method_signature (frame->runtime_method->method)->params [ac->rank];
+       MonoType *mt = mono_method_signature (frame->runtime_method->method)->params [ac->rank];
        stackval_to_data (mt, &sp [ac->rank], ea, FALSE);
 }
 
-static void 
+static void
 ves_array_get (MonoInvocation *frame)
 {
        stackval *sp = frame->stack_args + 1;
-       MonoObject *o;
-       MonoArray *ao;
-       MonoClass *ac;
-       gint32 i, t, pos, esize;
-       gpointer ea;
-       MonoType *mt;
 
-       o = frame->stack_args->data.p;
-       ao = (MonoArray *)o;
-       ac = o->vtable->klass;
+       MonoObject *o = frame->stack_args->data.p;
+       MonoArray *ao = (MonoArray *) o;
+       MonoClass *ac = o->vtable->klass;
 
        g_assert (ac->rank >= 1);
 
-       pos = sp [0].data.i;
-       if (ao->bounds != NULL) {
-               pos -= ao->bounds [0].lower_bound;
-               for (i = 1; i < ac->rank; i++) {
-                       if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >= 
-                           ao->bounds [i].length) {
-                               frame->ex = mono_get_exception_index_out_of_range ();
-                               FILL_IN_TRACE(frame->ex, frame);
-                               return;
-                       }
-
-                       pos = pos*ao->bounds [i].length + sp [i].data.i - 
-                               ao->bounds [i].lower_bound;
-               }
-       } else if (pos >= ao->max_length) {
-               frame->ex = mono_get_exception_index_out_of_range ();
-               FILL_IN_TRACE(frame->ex, frame);
+       gint32 pos = ves_array_calculate_index (ao, sp, frame);
+       if (frame->ex)
                return;
-       }
 
-       esize = mono_array_element_size (ac);
-       ea = mono_array_addr_with_size (ao, esize, pos);
+       gint32 esize = mono_array_element_size (ac);
+       gpointer ea = mono_array_addr_with_size (ao, esize, pos);
 
-       mt = mono_method_signature (frame->runtime_method->method)->ret;
+       MonoType *mt = mono_method_signature (frame->runtime_method->method)->ret;
        stackval_from_data (mt, frame->retval, ea, FALSE);
 }
 
 static gpointer
 ves_array_element_address (MonoInvocation *frame, MonoClass *required_type, MonoArray *ao, stackval *sp, gboolean needs_typecheck)
 {
-       gint32 i, pos, esize;
        MonoClass *ac = ((MonoObject *) ao)->vtable->klass;
 
        g_assert (ac->rank >= 1);
 
-       pos = sp [0].data.i;
-       if (ao->bounds != NULL) {
-               pos -= ao->bounds [0].lower_bound;
-               for (i = 1; i < ac->rank; i++) {
-                       if ((sp [i].data.i - ao->bounds [i].lower_bound) >= ao->bounds [i].length) {
-                               frame->ex = mono_get_exception_index_out_of_range ();
-                               FILL_IN_TRACE(frame->ex, frame);
-                               return NULL;
-                       }
-                       pos = pos * ao->bounds [i].length + sp [i].data.i - ao->bounds [i].lower_bound;
-               }
-       } else if (pos >= ao->max_length) {
-               frame->ex = mono_get_exception_index_out_of_range ();
-               FILL_IN_TRACE(frame->ex, frame);
+       gint32 pos = ves_array_calculate_index (ao, sp, frame);
+       if (frame->ex)
                return NULL;
-       }
 
        if (needs_typecheck && !mono_class_is_assignable_from (mono_object_class ((MonoObject *) ao)->element_class, required_type->element_class)) {
                frame->ex = mono_get_exception_array_type_mismatch ();
                FILL_IN_TRACE (frame->ex, frame);
                return NULL;
        }
-       esize = mono_array_element_size (ac);
+       gint32 esize = mono_array_element_size (ac);
        return mono_array_addr_with_size (ao, esize, pos);
 }
 
@@ -718,8 +696,6 @@ interp_walk_stack_with_ctx (MonoInternalStackWalk func, MonoContext *ctx, MonoUn
                        return;
                frame = frame->parent;
        }
-
-       g_assert (0);
 }
 
 static MonoPIFunc mono_interp_enter_icall_trampoline = NULL;
@@ -820,13 +796,19 @@ static MethodArguments* build_args_from_sig (MonoMethodSignature *sig, MonoInvoc
                case MONO_TYPE_GENERICINST:
                        margs->iargs [int_i] = frame->stack_args [i].data.p;
 #if DEBUG_INTERP
-                       g_print ("build_args_from_sig: margs->iargs[%d]: %p (frame @ %d)\n", int_i, margs->iargs[int_i], i);
+                       g_print ("build_args_from_sig: margs->iargs [%d]: %p (frame @ %d)\n", int_i, margs->iargs [int_i], i);
 #endif
                        int_i++;
                        break;
                case MONO_TYPE_R4:
                case MONO_TYPE_R8:
-                       margs->fargs [int_f] = frame->stack_args [i].data.f;
+                       if (ptype == MONO_TYPE_R4)
+                               * (float *) &(margs->fargs [int_f]) = (float) frame->stack_args [i].data.f;
+                       else
+                               margs->fargs [int_f] = frame->stack_args [i].data.f;
+#if DEBUG_INTERP
+                       g_print ("build_args_from_sig: margs->fargs [%d]: %p (%f) (frame @ %d)\n", int_f, margs->fargs [int_f], margs->fargs [int_f], i);
+#endif
                        int_f++;
                        break;
                default:
@@ -913,10 +895,15 @@ ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFuncV a
        /* domain can only be changed by native code */
        context->domain = mono_domain_get ();
 
-       if (*mono_thread_interruption_request_flag ())
-               mono_thread_interruption_checkpoint ();
+       if (*mono_thread_interruption_request_flag ()) {
+               MonoException *exc = mono_thread_interruption_checkpoint ();
+               if (exc) {
+                       frame->ex = exc;
+                       context->search_for_handler = 1;
+               }
+       }
        
-       if (!MONO_TYPE_ISSTRUCT (sig->ret))
+       if (!frame->ex && !MONO_TYPE_ISSTRUCT (sig->ret))
                stackval_from_data (sig->ret, frame->retval, (char*)&frame->retval->data.p, sig->pinvoke);
 
        context->current_frame = old_frame;
@@ -1241,6 +1228,8 @@ mono_interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoOb
        jmp_buf env;
 
        error_init (error);
+       if (exc)
+               *exc = NULL;
 
        frame.ex = NULL;
 
@@ -1344,6 +1333,7 @@ handle_enum:
                case MONO_TYPE_ARRAY:
                case MONO_TYPE_SZARRAY:
                case MONO_TYPE_OBJECT:
+               case MONO_TYPE_GENERICINST:
                        args [a_index].data.p = params [i];
                        break;
                default:
@@ -1476,27 +1466,35 @@ static mono_mutex_t create_method_pointer_mutex;
 
 static GHashTable *method_pointer_hash = NULL;
 
-static MonoMethod *method_pointers [2] = {0};
+#define TRAMPS_USED 8
 
-static MonoObject *
-mp_tramp_0 (MonoObject *this_obj, void **params, MonoObject **exc, void *compiled_method) {
-       MonoError error;
-       void *params_real[] = {this_obj, &params, &exc, &compiled_method};
-       MonoObject *ret = mono_interp_runtime_invoke (method_pointers [0], NULL, params_real, NULL, &error);
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-       return ret;
-}
+static MonoMethod *method_pointers [TRAMPS_USED] = {0};
+
+#define GEN_METHOD_PTR_TRAMP(num) \
+               static MonoObject * mp_tramp_ ## num (MonoObject *this_obj, void **params, MonoObject **exc, void *compiled_method) { \
+                       MonoError error; \
+                       void *params_real[] = {this_obj, &params, &exc, &compiled_method}; \
+                       MonoObject *ret = mono_interp_runtime_invoke (method_pointers [num], NULL, params_real, NULL, &error); \
+                       mono_error_cleanup (&error); \
+                       return ret; \
+               }
 
-static MonoObject *
-mp_tramp_1 (MonoObject *this_obj, void **params, MonoObject **exc, void *compiled_method) {
-       MonoError error;
-       void *params_real[] = {this_obj, &params, &exc, &compiled_method};
-       MonoObject *ret = mono_interp_runtime_invoke (method_pointers [1], NULL, params_real, NULL, &error);
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-       return ret;
-}
 
-gpointer *mp_tramps[] = {(gpointer) mp_tramp_0, (gpointer) mp_tramp_1};
+GEN_METHOD_PTR_TRAMP (0);
+GEN_METHOD_PTR_TRAMP (1);
+GEN_METHOD_PTR_TRAMP (2);
+GEN_METHOD_PTR_TRAMP (3);
+GEN_METHOD_PTR_TRAMP (4);
+GEN_METHOD_PTR_TRAMP (5);
+GEN_METHOD_PTR_TRAMP (6);
+GEN_METHOD_PTR_TRAMP (7);
+
+#undef GEN_METHOD_PTR_TRAMP
+
+gpointer *mp_tramps[TRAMPS_USED] = {
+       (gpointer) mp_tramp_0, (gpointer) mp_tramp_1, (gpointer) mp_tramp_2, (gpointer) mp_tramp_3,
+       (gpointer) mp_tramp_4, (gpointer) mp_tramp_5, (gpointer) mp_tramp_6, (gpointer) mp_tramp_7
+};
 
 static int tramps_used = 0;
 
@@ -1532,7 +1530,7 @@ mono_interp_create_method_pointer (MonoMethod *method, MonoError *error)
        }               
        else {
                g_assert (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE);
-               g_assert (tramps_used < 2);
+               g_assert (tramps_used < TRAMPS_USED);
 
                /* FIXME: needs locking */
                method_pointers [tramps_used] = method;
@@ -1595,23 +1593,13 @@ static int opcode_counts[512];
 #define MINT_IN_DEFAULT default:
 #endif
 
-/* 
- * Defining this causes register allocation errors in some versions of gcc:
- * error: unable to find a register to spill in class `SIREG'
- */
-/* #define MINT_USE_DEDICATED_IP_REG */
-
 static void 
 ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
 {
        MonoInvocation child_frame;
        GSList *finally_ips = NULL;
        const unsigned short *endfinally_ip = NULL;
-#if defined(__GNUC__) && defined (i386) && defined (MINT_USE_DEDICATED_IP_REG)
-       register const unsigned short *ip asm ("%esi");
-#else
-       register const unsigned short *ip;
-#endif
+       const unsigned short *ip = NULL;
        register stackval *sp;
        RuntimeMethod *rtm;
 #if DEBUG_INTERP
@@ -1949,7 +1937,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
                                 * An exception occurred, need to run finally, fault and catch handlers..
                                 */
                                frame->ex = child_frame.ex;
-                               goto handle_finally;
+                               goto handle_exception;;
                        }
 
                        /* need to handle typedbyref ... */
@@ -1967,8 +1955,12 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
                        child_frame.retval = sp;
                        /* decrement by the actual number of args */
                        sp -= child_frame.runtime_method->param_count;
-                       if (child_frame.runtime_method->hasthis)
+                       if (child_frame.runtime_method->hasthis) {
                                --sp;
+                               MonoObject *this_arg = sp->data.p;
+                               if (!this_arg)
+                                       THROW_EX (mono_get_exception_null_reference(), ip - 2);
+                       }
                        child_frame.stack_args = sp;
 
                        if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->method->klass->valuetype && mono_object_is_transparent_proxy (sp->data.p)) {
@@ -2550,11 +2542,15 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
                MINT_IN_CASE(MINT_REM_I4)
                        if (sp [-1].data.i == 0)
                                THROW_EX (mono_get_exception_divide_by_zero (), ip);
+                       if (sp [-1].data.i == (-1))
+                               THROW_EX (mono_get_exception_overflow (), ip);
                        BINOP(i, %);
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_REM_I8)
                        if (sp [-1].data.l == 0)
                                THROW_EX (mono_get_exception_divide_by_zero (), ip);
+                       if (sp [-1].data.l == (-1))
+                               THROW_EX (mono_get_exception_overflow (), ip);
                        BINOP(l, %);
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_REM_R8)
@@ -2786,6 +2782,9 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
                        token = * (guint16 *)(ip + 1);
                        ip += 2;
 
+                       child_frame.ip = NULL;
+                       child_frame.ex = NULL;
+
                        child_frame.runtime_method = rtm->data_items [token];
                        csig = mono_method_signature (child_frame.runtime_method->method);
                        newobj_class = child_frame.runtime_method->method->klass;
@@ -2794,10 +2793,13 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
                                count++;
                                g_hash_table_insert (profiling_classes, newobj_class, GUINT_TO_POINTER (count));
                        }*/
-                               
+
                        if (newobj_class->parent == mono_defaults.array_class) {
                                sp -= csig->param_count;
-                               o = ves_array_create (context->domain, newobj_class, csig, sp);
+                               child_frame.stack_args = sp;
+                               o = ves_array_create (&child_frame, context->domain, newobj_class, csig, sp);
+                               if (child_frame.ex)
+                                       THROW_EX (child_frame.ex, ip);
                                goto array_constructed;
                        }
 
@@ -2837,9 +2839,6 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
 
                        g_assert (csig->call_convention == MONO_CALL_DEFAULT);
 
-                       child_frame.ip = NULL;
-                       child_frame.ex = NULL;
-
                        ves_exec_method_with_context (&child_frame, context);
 
                        context->current_frame = frame;
@@ -2915,6 +2914,11 @@ array_constructed:
                                sp->data.p = mono_get_exception_null_reference ();
                        THROW_EX ((MonoException *)sp->data.p, ip);
                        MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_LDFLDA_UNSAFE)
+                       o = sp [-1].data.p;
+                       sp[-1].data.p = (char *)o + * (guint16 *)(ip + 1);
+                       ip += 2;
+                       MINT_IN_BREAK;
                MINT_IN_CASE(MINT_LDFLDA)
                        o = sp [-1].data.p;
                        if (!o)
@@ -3155,9 +3159,19 @@ array_constructed:
                        sp [-1].data.l = sp [-1].data.i;
                        ++ip;
                        MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_CONV_OVF_U8_I8)
+                       if (sp [-1].data.l < 0)
+                               THROW_EX (mono_get_exception_overflow (), ip);
+                       ++ip;
+                       MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_CONV_OVF_I8_U8)
+                       if ((guint64) sp [-1].data.l > MYGINT64_MAX)
+                               THROW_EX (mono_get_exception_overflow (), ip);
+                       ++ip;
+                       MINT_IN_BREAK;
                MINT_IN_CASE(MINT_CONV_OVF_U8_R8)
                MINT_IN_CASE(MINT_CONV_OVF_I8_UN_R8)
-                       if (sp [-1].data.f < 0 || sp [-1].data.f > 9223372036854775807LL)
+                       if (sp [-1].data.f < 0 || sp [-1].data.f > MYGINT64_MAX)
                                THROW_EX (mono_get_exception_overflow (), ip);
                        sp [-1].data.l = (guint64)sp [-1].data.f;
                        ++ip;
@@ -3194,6 +3208,9 @@ array_constructed:
                }
                MINT_IN_CASE(MINT_NEWARR)
                        sp [-1].data.p = (MonoObject*) mono_array_new_checked (context->domain, rtm->data_items[*(guint16 *)(ip + 1)], sp [-1].data.i, &error);
+                       if (!mono_error_ok (&error)) {
+                               THROW_EX (mono_error_convert_to_exception (&error), ip);
+                       }
                        mono_error_cleanup (&error); /* FIXME: don't swallow the error */
                        ip += 2;
                        /*if (profiling_classes) {
@@ -3333,6 +3350,7 @@ array_constructed:
                }
                MINT_IN_CASE(MINT_STELEM_I)  /* fall through */
                MINT_IN_CASE(MINT_STELEM_I1) /* fall through */ 
+               MINT_IN_CASE(MINT_STELEM_U1) /* fall through */
                MINT_IN_CASE(MINT_STELEM_I2) /* fall through */
                MINT_IN_CASE(MINT_STELEM_I4) /* fall through */
                MINT_IN_CASE(MINT_STELEM_I8) /* fall through */
@@ -3359,6 +3377,9 @@ array_constructed:
                        case MINT_STELEM_I1:
                                mono_array_set ((MonoArray *)o, gint8, aindex, sp [2].data.i);
                                break;
+                       case MINT_STELEM_U1:
+                               mono_array_set ((MonoArray *) o, guint8, aindex, sp [2].data.i);
+                               break;
                        case MINT_STELEM_I2:
                                mono_array_set ((MonoArray *)o, gint16, aindex, sp [2].data.i);
                                break;
@@ -3405,7 +3426,13 @@ array_constructed:
                        ++ip;
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_CONV_OVF_I4_I8)
-                       if (sp [-1].data.l <= MYGINT32_MIN || sp [-1].data.l > MYGINT32_MAX)
+                       if (sp [-1].data.l < MYGINT32_MIN || sp [-1].data.l > MYGINT32_MAX)
+                               THROW_EX (mono_get_exception_overflow (), ip);
+                       sp [-1].data.i = (gint32) sp [-1].data.l;
+                       ++ip;
+                       MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_CONV_OVF_I4_U8)
+                       if (sp [-1].data.l < 0 || sp [-1].data.l > MYGINT32_MAX)
                                THROW_EX (mono_get_exception_overflow (), ip);
                        sp [-1].data.i = (gint32) sp [-1].data.l;
                        ++ip;
@@ -3754,13 +3781,6 @@ array_constructed:
                        MINT_IN_BREAK;
                }
 
-               MINT_IN_CASE(MINT_LDTHISA)
-                       g_error ("should not happen");
-                       // sp->data.p = &frame->obj;
-                       ++ip;
-                       ++sp; 
-                       MINT_IN_BREAK;
-
 #define LDARG(datamem, argtype) \
        sp->data.datamem = * (argtype *)(frame->args + * (guint16 *)(ip + 1)); \
        ip += 2; \
@@ -4047,8 +4067,9 @@ array_constructed:
                }
 die_on_ex:
                ex_obj = (MonoObject*)frame->ex;
-               mono_unhandled_exception (ex_obj);
-               exit (1);
+               MonoJitTlsData *jit_tls = (MonoJitTlsData *) mono_tls_get_jit_tls ();
+               jit_tls->abort_func (ex_obj);
+               g_assert_not_reached ();
        }
        handle_finally:
        {
@@ -4351,7 +4372,6 @@ mono_interp_init ()
 {
        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);
 
        mono_interp_transform_init ();
@@ -4373,16 +4393,6 @@ interp_regression_step (MonoImage *image, int verbose, int *total_run, int *tota
        cfailed = failed = run = 0;
        transform_time = elapsed = 0.0;
 
-#if 0
-       /* fixme: ugly hack - delete all previously compiled methods */
-       if (domain_jit_info (domain)) {
-               g_hash_table_destroy (domain_jit_info (domain)->jit_trampoline_hash);
-               domain_jit_info (domain)->jit_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
-               mono_internal_hash_table_destroy (&(domain->jit_code_hash));
-               mono_jit_code_hash_init (&(domain->jit_code_hash));
-       }
-#endif
-
        g_timer_start (timer);
        for (i = 0; i < mono_image_get_table_rows (image, MONO_TABLE_METHOD); ++i) {
                MonoObject *exc = NULL;
@@ -4514,7 +4524,7 @@ mono_interp_regression_list (int verbose, int count, char *images [])
        
        total_run = total = 0;
        for (i = 0; i < count; ++i) {
-               MonoAssembly *ass = mono_assembly_open (images [i], NULL);
+               MonoAssembly *ass = mono_assembly_open_predicate (images [i], FALSE, FALSE, NULL, NULL, NULL);
                if (!ass) {
                        g_warning ("failed to load assembly: %s", images [i]);
                        continue;