Merge pull request #2431 from alexanderkyte/tests_with_excludes
[mono.git] / mono / mini / mini-generic-sharing.c
index 187be3c426d3d3b8786278b3bb1faddbb915f62c..94312a18f43d315cecdfb76d58ce66d7325a12d2 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <mono/metadata/class.h>
 #include <mono/metadata/method-builder.h>
+#include <mono/metadata/reflection-internals.h>
 #include <mono/utils/mono-counters.h>
 
 #include "mini.h"
@@ -539,6 +540,7 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co
 
        case MONO_RGCTX_INFO_METHOD:
        case MONO_RGCTX_INFO_GENERIC_METHOD_CODE:
+       case MONO_RGCTX_INFO_GSHAREDVT_OUT_WRAPPER:
        case MONO_RGCTX_INFO_METHOD_RGCTX:
        case MONO_RGCTX_INFO_METHOD_CONTEXT:
        case MONO_RGCTX_INFO_REMOTING_INVOKE_WITH_CHECK:
@@ -642,6 +644,7 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co
 
                return &inflated_class->fields [i];
        }
+       case MONO_RGCTX_INFO_SIG_GSHAREDVT_IN_TRAMPOLINE_CALLI:
        case MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI: {
                MonoMethodSignature *sig = (MonoMethodSignature *)data;
                MonoMethodSignature *isig;
@@ -1042,6 +1045,19 @@ get_wrapper_shared_type (MonoType *t)
        t = mini_get_underlying_type (t);
 
        switch (t->type) {
+       case MONO_TYPE_I1:
+               /* This removes any attributes etc. */
+               return &mono_defaults.sbyte_class->byval_arg;
+       case MONO_TYPE_U1:
+               return &mono_defaults.byte_class->byval_arg;
+       case MONO_TYPE_I2:
+               return &mono_defaults.int16_class->byval_arg;
+       case MONO_TYPE_U2:
+               return &mono_defaults.uint16_class->byval_arg;
+       case MONO_TYPE_I4:
+               return &mono_defaults.int32_class->byval_arg;
+       case MONO_TYPE_U4:
+               return &mono_defaults.uint32_class->byval_arg;
        case MONO_TYPE_OBJECT:
        case MONO_TYPE_CLASS:
        case MONO_TYPE_SZARRAY:
@@ -1453,6 +1469,7 @@ static gpointer
 instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti,
                                  MonoGenericContext *context, MonoClass *klass)
 {
+       MonoError error;
        gpointer data;
        gboolean temporary;
 
@@ -1501,8 +1518,12 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
        }
        case MONO_RGCTX_INFO_TYPE:
                return data;
-       case MONO_RGCTX_INFO_REFLECTION_TYPE:
-               return mono_type_get_object (domain, (MonoType *)data);
+       case MONO_RGCTX_INFO_REFLECTION_TYPE: {
+               MonoReflectionType *ret = mono_type_get_object_checked (domain, (MonoType *)data, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+               return ret;
+       }
        case MONO_RGCTX_INFO_METHOD:
                return data;
        case MONO_RGCTX_INFO_GENERIC_METHOD_CODE: {
@@ -1521,6 +1542,33 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
                        return mini_add_method_trampoline ((MonoMethod *)data, addr, mono_method_needs_static_rgctx_invoke ((MonoMethod *)data, FALSE), FALSE);
                }
        }
+       case MONO_RGCTX_INFO_GSHAREDVT_OUT_WRAPPER: {
+               MonoMethod *m = (MonoMethod*)data;
+               gpointer addr;
+               gpointer arg = NULL;
+
+               g_assert (mono_llvm_only);
+
+               addr = mono_compile_method (m);
+
+               MonoJitInfo *ji;
+               gboolean callee_gsharedvt;
+
+               ji = mini_jit_info_table_find (mono_domain_get (), (char *)mono_get_addr_from_ftnptr (addr), NULL);
+               g_assert (ji);
+               callee_gsharedvt = mini_jit_info_is_gsharedvt (ji);
+               if (callee_gsharedvt)
+                       callee_gsharedvt = mini_is_gsharedvt_variable_signature (mono_method_signature (jinfo_get_method (ji)));
+               if (callee_gsharedvt) {
+                       /* No need for a wrapper */
+                       return mini_create_llvmonly_ftndesc (domain, addr, mini_method_get_rgctx (m));
+               } else {
+                       addr = mini_add_method_wrappers_llvmonly (m, addr, TRUE, FALSE, &arg);
+
+                       /* Returns an ftndesc */
+                       return mini_create_llvmonly_ftndesc (domain, addr, arg);
+               }
+       }
        case MONO_RGCTX_INFO_VIRT_METHOD_CODE: {
                MonoJumpInfoVirtMethod *info = (MonoJumpInfoVirtMethod *)data;
                MonoClass *iface_class = info->method->klass;
@@ -1613,6 +1661,17 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
 
                return method->context.method_inst;
        }
+       case MONO_RGCTX_INFO_SIG_GSHAREDVT_IN_TRAMPOLINE_CALLI: {
+               MonoMethodSignature *gsig = (MonoMethodSignature *)oti->data;
+               MonoMethodSignature *sig = (MonoMethodSignature *)data;
+               gpointer addr;
+
+               /*
+                * This is an indirect call to the address passed by the caller in the rgctx reg.
+                */
+               addr = mini_get_gsharedvt_wrapper (TRUE, NULL, sig, gsig, -1, TRUE);
+               return addr;
+       }
        case MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI: {
                MonoMethodSignature *gsig = (MonoMethodSignature *)oti->data;
                MonoMethodSignature *sig = (MonoMethodSignature *)data;
@@ -1748,10 +1807,7 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
 
                                        gpointer in_wrapper_arg = mini_create_llvmonly_ftndesc (domain, callee_ji->code_start, mini_method_get_rgctx (method));
 
-                                       gpointer out_wrapper = mini_get_gsharedvt_wrapper (FALSE, NULL, sig, gsig, -1, FALSE);
-                                       MonoFtnDesc *out_wrapper_arg = mini_create_llvmonly_ftndesc (domain, in_wrapper, in_wrapper_arg);
-
-                                       addr = mini_create_llvmonly_ftndesc (domain, out_wrapper, out_wrapper_arg);
+                                       addr = mini_create_llvmonly_ftndesc (domain, in_wrapper, in_wrapper_arg);
                                } else {
                                        addr = mini_create_llvmonly_ftndesc (domain, addr, mini_method_get_rgctx (method));
                                }
@@ -1864,6 +1920,7 @@ mono_rgctx_info_type_to_str (MonoRgctxInfoType type)
        case MONO_RGCTX_INFO_METHOD: return "METHOD";
        case MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO: return "GSHAREDVT_INFO";
        case MONO_RGCTX_INFO_GENERIC_METHOD_CODE: return "GENERIC_METHOD_CODE";
+       case MONO_RGCTX_INFO_GSHAREDVT_OUT_WRAPPER: return "GSHAREDVT_OUT_WRAPPER";
        case MONO_RGCTX_INFO_CLASS_FIELD: return "CLASS_FIELD";
        case MONO_RGCTX_INFO_METHOD_RGCTX: return "METHOD_RGCTX";
        case MONO_RGCTX_INFO_METHOD_CONTEXT: return "METHOD_CONTEXT";
@@ -1876,6 +1933,7 @@ mono_rgctx_info_type_to_str (MonoRgctxInfoType type)
        case MONO_RGCTX_INFO_FIELD_OFFSET: return "FIELD_OFFSET";
        case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE: return "METHOD_GSHAREDVT_OUT_TRAMPOLINE";
        case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT: return "METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT";
+       case MONO_RGCTX_INFO_SIG_GSHAREDVT_IN_TRAMPOLINE_CALLI: return "SIG_GSHAREDVT_IN_TRAMPOLINE_CALLI";
        case MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI: return "SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI";
        case MONO_RGCTX_INFO_MEMCPY: return "MEMCPY";
        case MONO_RGCTX_INFO_BZERO: return "BZERO";
@@ -1968,6 +2026,7 @@ info_equal (gpointer data1, gpointer data2, MonoRgctxInfoType info_type)
        case MONO_RGCTX_INFO_METHOD:
        case MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO:
        case MONO_RGCTX_INFO_GENERIC_METHOD_CODE:
+       case MONO_RGCTX_INFO_GSHAREDVT_OUT_WRAPPER:
        case MONO_RGCTX_INFO_CLASS_FIELD:
        case MONO_RGCTX_INFO_FIELD_OFFSET:
        case MONO_RGCTX_INFO_METHOD_RGCTX:
@@ -1976,6 +2035,7 @@ info_equal (gpointer data1, gpointer data2, MonoRgctxInfoType info_type)
        case MONO_RGCTX_INFO_METHOD_DELEGATE_CODE:
        case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE:
        case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT:
+       case MONO_RGCTX_INFO_SIG_GSHAREDVT_IN_TRAMPOLINE_CALLI:
        case MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI:
                return data1 == data2;
        case MONO_RGCTX_INFO_VIRT_METHOD_CODE: