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;
}
} 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;
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;
}
}
- 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 void
-ves_array_element_address (MonoInvocation *frame)
+static gpointer
+ves_array_element_address (MonoInvocation *frame, MonoClass *required_type, MonoArray *ao, stackval *sp, gboolean needs_typecheck)
{
- stackval *sp = frame->stack_args + 1;
- MonoObject *o;
- MonoArray *ao;
- MonoClass *ac;
- gint32 i, t, pos, esize;
- gpointer ea;
-
- o = frame->stack_args->data.p;
- ao = (MonoArray *)o;
- ac = o->vtable->klass;
+ 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 ((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);
- return;
- }
-
- esize = mono_array_element_size (ac);
- ea = mono_array_addr_with_size (ao, esize, pos);
+ gint32 pos = ves_array_calculate_index (ao, sp, frame);
+ if (frame->ex)
+ return NULL;
- frame->retval->data.p = ea;
+ 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;
+ }
+ gint32 esize = mono_array_element_size (ac);
+ return mono_array_addr_with_size (ao, esize, pos);
}
void
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:
/* 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;
ves_array_get (frame);
return;
}
- if (*name == 'A' && (strcmp (name, "Address") == 0)) {
- ves_array_element_address (frame);
- return;
- }
}
g_error ("Don't know how to exec runtime method %s.%s::%s",
* 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 ... */
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)) {
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)
sp [-1].data.l = (guint64)sp [-1].data.f;
++ip;
MINT_IN_BREAK;
-#if 0
MINT_IN_CASE(MINT_CPOBJ) {
- MonoClass *vtklass;
- ++ip;
- vtklass = rtm->data_items[READ32 (ip)];
+ c = rtm->data_items[* (guint16 *)(ip + 1)];
+ g_assert (c->byval_arg.type == MONO_TYPE_VALUETYPE);
+ stackval_from_data (&c->byval_arg, &sp [-2], sp [-1].data.p, FALSE);
ip += 2;
sp -= 2;
- memcpy (sp [0].data.p, sp [1].data.p, mono_class_value_size (vtklass, NULL));
MINT_IN_BREAK;
}
-#endif
MINT_IN_CASE(MINT_LDOBJ) {
void *p;
c = rtm->data_items[* (guint16 *)(ip + 1)];
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;
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;
}
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;
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)
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;
}
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) {
MINT_IN_CASE(MINT_LDELEMA)
MINT_IN_CASE(MINT_LDELEMA_TC) {
gboolean needs_typecheck = *ip == MINT_LDELEMA_TC;
- guint32 esize;
- mono_u aindex;
MonoClass *klass = rtm->data_items [*(guint16 *) (ip + 1)];
- ip += 2;
- sp -= 2;
+ guint16 numargs = *(guint16 *) (ip + 2);
+ ip += 3;
+ sp -= numargs;
o = sp [0].data.p;
-
- aindex = sp [1].data.i;
- if (aindex >= mono_array_length ((MonoArray *) o))
- THROW_EX (mono_get_exception_index_out_of_range (), ip - 2);
-
- if (needs_typecheck && o->vtable->klass->element_class != klass)
- THROW_EX (mono_get_exception_array_type_mismatch (), ip);
-
- esize = mono_array_element_size (((MonoArray *) o)->obj.vtable->klass);
- sp->data.p = mono_array_addr_with_size ((MonoArray *) o, esize, aindex);
-
+ sp->data.p = ves_array_element_address (frame, klass, (MonoArray *) o, &sp [1], needs_typecheck);
+ if (frame->ex)
+ THROW_EX (frame->ex, ip);
++sp;
+
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_LDELEM_I1) /* fall through */
}
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 */
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;
++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;
{
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 ();
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;