#endif
#include "jit-icalls.h"
-
+#include <mono/utils/mono-error-internals.h>
void*
mono_ldftn (MonoMethod *method)
{
gpointer addr;
- MONO_ARCH_SAVE_REGS;
-
addr = mono_create_jump_trampoline (mono_domain_get (), method, FALSE);
return mono_create_ftnptr (mono_domain_get (), addr);
static void*
ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared)
{
+ MonoError error;
MonoMethod *res;
- MONO_ARCH_SAVE_REGS;
-
- if (obj == NULL)
- mono_raise_exception (mono_get_exception_null_reference ());
+ if (obj == NULL) {
+ mono_set_pending_exception (mono_get_exception_null_reference ());
+ return NULL;
+ }
res = mono_object_get_virtual_method (obj, method);
context.class_inst = res->klass->generic_container->context.class_inst;
context.method_inst = mono_method_get_context (method)->method_inst;
- res = mono_class_inflate_generic_method (res, &context);
+ res = mono_class_inflate_generic_method_checked (res, &context, &error);
+ mono_error_raise_exception (&error);
}
/* An rgctx wrapper is added by the trampolines no need to do it here */
void
mono_helper_stelem_ref_check (MonoArray *array, MonoObject *val)
{
- MONO_ARCH_SAVE_REGS;
-
- if (!array)
- mono_raise_exception (mono_get_exception_null_reference ());
- if (val && !mono_object_isinst (val, array->obj.vtable->klass->element_class))
- mono_raise_exception (mono_get_exception_array_type_mismatch ());
+ if (!array) {
+ mono_set_pending_exception (mono_get_exception_null_reference ());
+ return;
+ }
+ if (val && !mono_object_isinst (val, array->obj.vtable->klass->element_class)) {
+ mono_set_pending_exception (mono_get_exception_array_type_mismatch ());
+ return;
+ }
}
-#ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
+#if !defined(MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS) || defined(MONO_ARCH_EMULATE_LONG_MUL_OVF_OPTS)
gint64
mono_llmult (gint64 a, gint64 b)
{
- /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
return a * b;
}
guint32 bh = b >> 32;
guint64 res, t1;
- MONO_ARCH_SAVE_REGS;
-
// fixme: this is incredible slow
if (ah && bh)
return res;
raise_exception:
- mono_raise_exception (mono_get_exception_overflow ());
+ mono_set_pending_exception (mono_get_exception_overflow ());
return 0;
}
gint64 res, t1;
gint32 sign;
- MONO_ARCH_SAVE_REGS;
-
/* need to work with absoulte values, so find out what the
resulting sign will be and convert any negative numbers
from two's complement
return res;
raise_exception:
- mono_raise_exception (mono_get_exception_overflow ());
+ mono_set_pending_exception (mono_get_exception_overflow ());
return 0;
}
gint64
mono_lldiv (gint64 a, gint64 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
- else if (b == -1 && a == (-9223372036854775807LL - 1LL))
- mono_raise_exception (mono_get_exception_arithmetic ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
+ else if (b == -1 && a == (-9223372036854775807LL - 1LL)) {
+ mono_set_pending_exception (mono_get_exception_arithmetic ());
+ return 0;
+ }
#endif
return a / b;
}
gint64
mono_llrem (gint64 a, gint64 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
- else if (b == -1 && a == (-9223372036854775807LL - 1LL))
- mono_raise_exception (mono_get_exception_arithmetic ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
+ else if (b == -1 && a == (-9223372036854775807LL - 1LL)) {
+ mono_set_pending_exception (mono_get_exception_arithmetic ());
+ return 0;
+ }
#endif
return a % b;
}
guint64
mono_lldiv_un (guint64 a, guint64 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
#endif
return a / b;
}
guint64
mono_llrem_un (guint64 a, guint64 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
#endif
return a % b;
}
{
guint64 res;
- /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
- res = a << shamt;
+ res = a << (shamt & 0x7f);
/*printf ("TESTL %lld << %d = %lld\n", a, shamt, res);*/
{
guint64 res;
- /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
- res = a >> shamt;
+ res = a >> (shamt & 0x7f);
/*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
{
gint64 res;
- /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
- res = a >> shamt;
+ res = a >> (shamt & 0x7f);
/*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
gint32
mono_idiv (gint32 a, gint32 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
- else if (b == -1 && a == (0x80000000))
- mono_raise_exception (mono_get_exception_overflow ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
+ else if (b == -1 && a == (0x80000000)) {
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
+ }
#endif
return a / b;
}
guint32
mono_idiv_un (guint32 a, guint32 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
#endif
return a / b;
}
gint32
mono_irem (gint32 a, gint32 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
- else if (b == -1 && a == (0x80000000))
- mono_raise_exception (mono_get_exception_overflow ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
+ else if (b == -1 && a == (0x80000000)) {
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
+ }
#endif
-
return a % b;
}
guint32
mono_irem_un (guint32 a, guint32 b)
{
- MONO_ARCH_SAVE_REGS;
-
#ifdef MONO_ARCH_NEED_DIV_CHECK
- if (!b)
- mono_raise_exception (mono_get_exception_divide_by_zero ());
+ if (!b) {
+ mono_set_pending_exception (mono_get_exception_divide_by_zero ());
+ return 0;
+ }
#endif
return a % b;
}
gint32
mono_imul (gint32 a, gint32 b)
{
- MONO_ARCH_SAVE_REGS;
-
return a * b;
}
{
gint64 res;
- MONO_ARCH_SAVE_REGS;
-
res = (gint64)a * (gint64)b;
- if ((res > 0x7fffffffL) || (res < -2147483648LL))
- mono_raise_exception (mono_get_exception_overflow ());
+ if ((res > 0x7fffffffL) || (res < -2147483648LL)) {
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
+ }
return res;
}
{
guint64 res;
- MONO_ARCH_SAVE_REGS;
-
res = (guint64)a * (guint64)b;
- if ((res >> 32))
- mono_raise_exception (mono_get_exception_overflow ());
+ if (res >> 32) {
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
+ }
return res;
}
double
mono_fdiv (double a, double b)
{
- MONO_ARCH_SAVE_REGS;
-
return a / b;
}
#endif
int rank;
int i, d;
- MONO_ARCH_SAVE_REGS;
-
pcount = mono_method_signature (cm)->param_count;
rank = cm->klass->rank;
int pcount;
int rank;
- MONO_ARCH_SAVE_REGS;
-
pcount = mono_method_signature (cm)->param_count;
rank = cm->klass->rank;
int pcount;
int rank;
- MONO_ARCH_SAVE_REGS;
-
pcount = mono_method_signature (cm)->param_count;
rank = cm->klass->rank;
int pcount;
int rank;
- MONO_ARCH_SAVE_REGS;
-
pcount = mono_method_signature (cm)->param_count;
rank = cm->klass->rank;
int pcount;
int rank;
- MONO_ARCH_SAVE_REGS;
-
pcount = mono_method_signature (cm)->param_count;
rank = cm->klass->rank;
MonoVTable *vtable;
gpointer addr;
- MONO_ARCH_SAVE_REGS;
-
//printf ("SFLDA0 %s.%s::%s %d\n", field->parent->name_space, field->parent->name, field->name, field->offset, field->parent->inited);
mono_class_init (field->parent);
gpointer
mono_ldtoken_wrapper (MonoImage *image, int token, MonoGenericContext *context)
{
+ MonoError error;
MonoClass *handle_class;
gpointer res;
- MONO_ARCH_SAVE_REGS;
- res = mono_ldtoken (image, token, &handle_class, context);
+ res = mono_ldtoken_checked (image, token, &handle_class, context, &error);
+ mono_error_raise_exception (&error);
mono_class_init (handle_class);
return res;
gint64
mono_fconv_i8 (double v)
{
- /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
return (gint64)v;
}
#endif
guint32
mono_fconv_u4 (double v)
{
- /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
+ /* MS.NET behaves like this for some reason */
+#ifdef HAVE_ISINF
+ if (isinf (v) || isnan (v))
+ return 0;
+#endif
+
return (guint32)v;
}
{
gint64 res;
- MONO_ARCH_SAVE_REGS;
-
res = (gint64)v;
if (isnan(v) || trunc (v) != res) {
- mono_raise_exception (mono_get_exception_overflow ());
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
}
return res;
}
{
guint64 res;
- MONO_ARCH_SAVE_REGS;
/*
* The soft-float implementation of some ARM devices have a buggy guin64 to double
* conversion that it looses precision even when the integer if fully representable
*/
#if defined(__arm__) && defined(MONO_ARCH_SOFT_FLOAT_FALLBACK)
if (isnan (v) || !(v >= -0.5 && v <= ULLONG_MAX+0.5)) {
- mono_raise_exception (mono_get_exception_overflow ());
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
}
res = (guint64)v;
#else
res = (guint64)v;
if (isnan(v) || trunc (v) != res) {
- mono_raise_exception (mono_get_exception_overflow ());
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
}
#endif
return res;
}
+#ifdef MONO_ARCH_EMULATE_FCONV_TO_I8
+gint64
+mono_rconv_i8 (float v)
+{
+ return (gint64)v;
+}
+#endif
+
+gint64
+mono_rconv_ovf_i8 (float v)
+{
+ gint64 res;
+
+ res = (gint64)v;
+
+ if (isnan(v) || trunc (v) != res) {
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
+ }
+ return res;
+}
+
+guint64
+mono_rconv_ovf_u8 (float v)
+{
+ guint64 res;
+
+ res = (guint64)v;
+ if (isnan(v) || trunc (v) != res) {
+ mono_set_pending_exception (mono_get_exception_overflow ());
+ return 0;
+ }
+ return res;
+}
+
#ifdef MONO_ARCH_EMULATE_LCONV_TO_R8
double
mono_lconv_to_r8 (gint64 a)
mono_jit_stats.generic_virtual_invocations++;
- if (obj == NULL)
- mono_raise_exception (mono_get_exception_null_reference ());
+ if (obj == NULL) {
+ mono_set_pending_exception (mono_get_exception_null_reference ());
+ return NULL;
+ }
vmethod = mono_object_get_virtual_method (obj, method);
g_assert (!vmethod->klass->generic_container);
g_assert (!vmethod->klass->generic_class || !vmethod->klass->generic_class->context.class_inst->is_open);
addr = mono_compile_method (vmethod);
- if (mono_method_needs_static_rgctx_invoke (vmethod, FALSE))
- addr = mono_create_static_rgctx_trampoline (vmethod, addr);
+ addr = mini_add_method_trampoline (NULL, vmethod, addr, mono_method_needs_static_rgctx_invoke (vmethod, FALSE), FALSE);
/* Since this is a virtual call, have to unbox vtypes */
if (obj->vtable->klass->valuetype)
MonoObject*
mono_helper_newobj_mscorlib (guint32 idx)
{
- MonoClass *klass = mono_class_get (mono_defaults.corlib, MONO_TOKEN_TYPE_DEF | idx);
-
- g_assert (klass);
+ MonoError error;
+ MonoClass *klass = mono_class_get_checked (mono_defaults.corlib, MONO_TOKEN_TYPE_DEF | idx, &error);
+ mono_error_raise_exception (&error);
return mono_object_new (mono_domain_get (), klass);
}
}
MonoObject*
-mono_object_castclass (MonoObject *obj, MonoClass *klass)
+mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass)
{
MonoJitTlsData *jit_tls = NULL;
+ MonoClass *oklass;
if (mini_get_debug_options ()->better_cast_details) {
jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
if (!obj)
return NULL;
+ oklass = obj->vtable->klass;
+ if ((klass->enumtype && oklass == klass->element_class) || (oklass->enumtype && klass == oklass->element_class))
+ return obj;
if (mono_object_isinst (obj, klass))
return obj;
if (mini_get_debug_options ()->better_cast_details) {
- jit_tls->class_cast_from = obj->vtable->klass;
+ jit_tls->class_cast_from = oklass;
jit_tls->class_cast_to = klass;
}
- mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
+ mono_set_pending_exception (mono_exception_from_name (mono_defaults.corlib,
"System", "InvalidCastException"));
return NULL;
jit_tls->class_cast_to = klass;
}
- mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
+ mono_set_pending_exception (mono_exception_from_name (mono_defaults.corlib,
"System", "InvalidCastException"));
return NULL;
MonoMethod *m;
int vt_slot;
- /* Lookup the virtual method */
- mono_class_setup_vtable (klass);
- g_assert (klass->vtable);
- vt_slot = mono_method_get_vtable_slot (cmethod);
- if (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
- int iface_offset;
+ if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ mono_set_pending_exception (mono_get_exception_execution_engine ("Not yet supported."));
+ return NULL;
+ }
- iface_offset = mono_class_interface_offset (klass, cmethod->klass);
- g_assert (iface_offset);
- vt_slot += iface_offset;
+ if (mono_method_signature (cmethod)->pinvoke) {
+ /* Object.GetType () */
+ m = mono_marshal_get_native_wrapper (cmethod, TRUE, FALSE);
+ } else {
+ /* Lookup the virtual method */
+ mono_class_setup_vtable (klass);
+ g_assert (klass->vtable);
+ vt_slot = mono_method_get_vtable_slot (cmethod);
+ if (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ int iface_offset;
+
+ iface_offset = mono_class_interface_offset (klass, cmethod->klass);
+ g_assert (iface_offset != -1);
+ vt_slot += iface_offset;
+ }
+ m = klass->vtable [vt_slot];
+ if (cmethod->is_inflated)
+ m = mono_class_inflate_generic_method (m, mono_method_get_context (cmethod));
}
- m = klass->vtable [vt_slot];
if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class))
/*
* Calling a non-vtype method with a vtype receiver, has to box.
return m;
}
-MonoObject*
-mono_object_tostring_gsharedvt (gpointer mp, MonoMethod *cmethod, MonoClass *klass)
-{
- MonoMethod *m;
- gpointer this_arg;
-
- m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg);
- return mono_runtime_invoke (m, this_arg, NULL, NULL);
-}
-
-int
-mono_object_gethashcode_gsharedvt (gpointer mp, MonoMethod *cmethod, MonoClass *klass)
-{
- MonoMethod *m;
- gpointer this_arg;
- MonoObject *res;
- gpointer p;
-
- m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg);
- // FIXME: This boxes the result
- res = mono_runtime_invoke (m, this_arg, NULL, NULL);
- p = mono_object_unbox (res);
- return *(int*)p;
-}
-
-MonoBoolean
-mono_object_equals_gsharedvt (gpointer mp, MonoMethod *cmethod, MonoClass *klass, MonoObject *arg)
-{
- MonoMethod *m;
- gpointer this_arg;
- MonoObject *res;
- gpointer p;
- void **args;
-
- m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg);
- // FIXME: This boxes the result
- args = (void**)&arg;
- res = mono_runtime_invoke (m, this_arg, args, NULL);
- p = mono_object_unbox (res);
- return *(MonoBoolean*)p;
-}
-
/*
* mono_gsharedvt_constrained_call:
*
* Make a call to CMETHOD using the receiver MP, which is assumed to be of type KLASS. ARGS contains
* the arguments to the method in the format used by mono_runtime_invoke ().
*/
-void
-mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *args)
+MonoObject*
+mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args)
{
MonoMethod *m;
gpointer this_arg;
+ gpointer new_args [16];
m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg);
- mono_runtime_invoke (m, this_arg, args, NULL);
+ if (args && deref_arg) {
+ new_args [0] = *(gpointer*)args [0];
+ args = new_args;
+ }
+ if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ /* Object.GetType () */
+ args = new_args;
+ args [0] = this_arg;
+ this_arg = NULL;
+ }
+ return mono_runtime_invoke (m, this_arg, args, NULL);
}
void