[jit] Fix some issues with constrained gsharedvt calls to be able to handle some...
[mono.git] / mono / mini / jit-icalls.c
index 10fd50a5603c4ae831a8c9a38fd1384931ee3f8b..1f7e5283767aab5144d50a5d5883b1573547a965 100644 (file)
@@ -17,7 +17,7 @@
 #endif
 
 #include "jit-icalls.h"
-
+#include <mono/utils/mono-error-internals.h>
 void*
 mono_ldftn (MonoMethod *method)
 {
@@ -33,6 +33,7 @@ mono_ldftn (MonoMethod *method)
 static void*
 ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared)
 {
+       MonoError error;
        MonoMethod *res;
 
        MONO_ARCH_SAVE_REGS;
@@ -51,7 +52,8 @@ ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared)
                        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 */
@@ -82,7 +84,7 @@ mono_helper_stelem_ref_check (MonoArray *array, MonoObject *val)
                mono_raise_exception (mono_get_exception_array_type_mismatch ());
 }
 
-#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)
@@ -825,11 +827,13 @@ mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
 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;
@@ -936,6 +940,39 @@ mono_fconv_ovf_u8 (double v)
        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_raise_exception (mono_get_exception_overflow ());
+       }
+       return res;
+}
+
+guint64
+mono_rconv_ovf_u8 (float v)
+{
+       guint64 res;
+
+       res = (guint64)v;
+       if (isnan(v) || trunc (v) != res) {
+               mono_raise_exception (mono_get_exception_overflow ());
+       }
+       return res;
+}
+
 #ifdef MONO_ARCH_EMULATE_LCONV_TO_R8
 double
 mono_lconv_to_r8 (gint64 a)
@@ -996,8 +1033,7 @@ mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointe
 
        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)
@@ -1023,9 +1059,9 @@ mono_helper_ldstr_mscorlib (guint32 idx)
 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);
 }
@@ -1062,6 +1098,7 @@ MonoObject*
 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);
@@ -1071,13 +1108,14 @@ mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass)
        if (!obj)
                return NULL;
 
-       if (klass->enumtype && obj->vtable->klass == klass->element_class)
+       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;
        }
 
@@ -1188,6 +1226,8 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
                        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));
        }
        if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class))
                /*