Use g_assertion_message instead of exit to kill an iOS app.
[mono.git] / mono / mini / jit-icalls.c
index b332d00204f58dceac179bb0d80705a45db42c8a..7f485f74f2a9da6ae01c23046bbcfc4000cd6860 100644 (file)
@@ -6,6 +6,8 @@
  *   Paolo Molaro (lupus@ximian.com)
  *
  * (C) 2002 Ximian, Inc.
+ * Copyright 2003-2011 Novell Inc (http://www.novell.com)
+ * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
  */
 #include <config.h>
 #include <math.h>
@@ -74,6 +76,8 @@ 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 ());
 }
@@ -230,51 +234,48 @@ mono_llmult_ovf (gint64 a, gint64 b)
        return 0;
 }
 
-#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV)
-
-gint32
-mono_idiv (gint32 a, gint32 b)
+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 == (0x80000000))
+       else if (b == -1 && a == (-9223372036854775807LL - 1LL))
                mono_raise_exception (mono_get_exception_arithmetic ());
 #endif
        return a / b;
 }
 
-guint32
-mono_idiv_un (guint32 a, guint32 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 ());
 #endif
-       return a / b;
+       return a % b;
 }
 
-gint32
-mono_irem (gint32 a, gint32 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 ());
-       else if (b == -1 && a == (0x80000000))
-               mono_raise_exception (mono_get_exception_arithmetic ());
 #endif
-
-       return a % b;
+       return a / b;
 }
 
-guint32
-mono_irem_un (guint32 a, guint32 b)
+guint64 
+mono_llrem_un (guint64 a, guint64 b)
 {
        MONO_ARCH_SAVE_REGS;
 
@@ -287,99 +288,94 @@ mono_irem_un (guint32 a, guint32 b)
 
 #endif
 
-#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_MUL_OVF)
-
-gint32
-mono_imul (gint32 a, gint32 b)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       return a * b;
-}
+#ifndef MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
 
-gint32
-mono_imul_ovf (gint32 a, gint32 b)
+guint64 
+mono_lshl (guint64 a, gint32 shamt)
 {
-       gint64 res;
-
-       MONO_ARCH_SAVE_REGS;
+       guint64 res;
 
-       res = (gint64)a * (gint64)b;
+       /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
+       res = a << shamt;
 
-       if ((res > 0x7fffffffL) || (res < -2147483648LL))
-               mono_raise_exception (mono_get_exception_overflow ());
+       /*printf ("TESTL %lld << %d = %lld\n", a, shamt, res);*/
 
        return res;
 }
 
-gint32
-mono_imul_ovf_un (guint32 a, guint32 b)
+guint64 
+mono_lshr_un (guint64 a, gint32 shamt)
 {
        guint64 res;
 
-       MONO_ARCH_SAVE_REGS;
-
-       res = (guint64)a * (guint64)b;
+       /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
+       res = a >> shamt;
 
-       if ((res >> 32))
-               mono_raise_exception (mono_get_exception_overflow ());
+       /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
 
        return res;
 }
-#endif
 
-#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT)
-double
-mono_fdiv (double a, double b)
+gint64 
+mono_lshr (gint64 a, gint32 shamt)
 {
-       MONO_ARCH_SAVE_REGS;
+       gint64 res;
 
-       return a / b;
+       /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
+       res = a >> shamt;
+
+       /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
+
+       return res;
 }
+
 #endif
 
-gint64 
-mono_lldiv (gint64 a, gint64 b)
+#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV)
+
+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 == (-9223372036854775807LL - 1LL))
-               mono_raise_exception (mono_get_exception_arithmetic ());
+       else if (b == -1 && a == (0x80000000))
+               mono_raise_exception (mono_get_exception_overflow ());
 #endif
        return a / b;
 }
 
-gint64 
-mono_llrem (gint64 a, gint64 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 ());
-       else if (b == -1 && a == (-9223372036854775807LL - 1LL))
-               mono_raise_exception (mono_get_exception_arithmetic ());
 #endif
-       return a % b;
+       return a / b;
 }
 
-guint64 
-mono_lldiv_un (guint64 a, guint64 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 ());
 #endif
-       return a / b;
+
+       return a % b;
 }
 
-guint64 
-mono_llrem_un (guint64 a, guint64 b)
+guint32
+mono_irem_un (guint32 a, guint32 b)
 {
        MONO_ARCH_SAVE_REGS;
 
@@ -392,47 +388,55 @@ mono_llrem_un (guint64 a, guint64 b)
 
 #endif
 
-#ifndef MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
+#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_MUL_OVF)
 
-guint64 
-mono_lshl (guint64 a, gint32 shamt)
+gint32
+mono_imul (gint32 a, gint32 b)
 {
-       guint64 res;
-
-       /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
-       res = a << shamt;
-
-       /*printf ("TESTL %lld << %d = %lld\n", a, shamt, res);*/
+       MONO_ARCH_SAVE_REGS;
 
-       return res;
+       return a * b;
 }
 
-guint64 
-mono_lshr_un (guint64 a, gint32 shamt)
+gint32
+mono_imul_ovf (gint32 a, gint32 b)
 {
-       guint64 res;
+       gint64 res;
 
-       /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
-       res = a >> shamt;
+       MONO_ARCH_SAVE_REGS;
 
-       /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
+       res = (gint64)a * (gint64)b;
+
+       if ((res > 0x7fffffffL) || (res < -2147483648LL))
+               mono_raise_exception (mono_get_exception_overflow ());
 
        return res;
 }
 
-gint64 
-mono_lshr (gint64 a, gint32 shamt)
+gint32
+mono_imul_ovf_un (guint32 a, guint32 b)
 {
-       gint64 res;
+       guint64 res;
 
-       /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
-       res = a >> shamt;
+       MONO_ARCH_SAVE_REGS;
 
-       /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
+       res = (guint64)a * (guint64)b;
+
+       if ((res >> 32))
+               mono_raise_exception (mono_get_exception_overflow ());
 
        return res;
 }
+#endif
 
+#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT)
+double
+mono_fdiv (double a, double b)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       return a / b;
+}
 #endif
 
 #ifdef MONO_ARCH_SOFT_FLOAT
@@ -782,7 +786,7 @@ mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
        if (domain->special_static_fields && (addr = g_hash_table_lookup (domain->special_static_fields, field)))
                addr = mono_get_special_static_data (GPOINTER_TO_UINT (addr));
        else
-               addr = (char*)vtable->data + field->offset;
+               addr = (char*)mono_vtable_get_static_field_data (vtable) + field->offset;
        
        return addr;
 }
@@ -926,6 +930,16 @@ mono_lconv_to_r8_un (guint64 a)
 }
 #endif
 
+#if defined(__native_client_codegen__) || defined(__native_client__)
+/* When we cross-compile to Native Client we can't directly embed calls */
+/* to the math library on the host. This will use the fmod on the target*/
+double
+mono_fmod(double a, double b)
+{
+       return fmod(a, b);
+}
+#endif
+
 gpointer
 mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointer *this_arg)
 {
@@ -1012,7 +1026,7 @@ mono_object_castclass (MonoObject *obj, MonoClass *klass)
        MonoJitTlsData *jit_tls = NULL;
 
        if (mini_get_debug_options ()->better_cast_details) {
-               jit_tls = TlsGetValue (mono_jit_tls_id);
+               jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
                jit_tls->class_cast_from = NULL;
        }
 
@@ -1040,7 +1054,7 @@ mono_object_castclass_with_cache (MonoObject *obj, MonoClass *klass, gpointer *c
        gpointer cached_vtable, obj_vtable;
 
        if (mini_get_debug_options ()->better_cast_details) {
-               jit_tls = TlsGetValue (mono_jit_tls_id);
+               jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
                jit_tls->class_cast_from = NULL;
        }