[interp] Don't share interp_in signatures for different valuetypes (#36520)
authormonojenkins <jo.shields+jenkins@xamarin.com>
Sat, 16 May 2020 20:47:39 +0000 (16:47 -0400)
committerGitHub <noreply@github.com>
Sat, 16 May 2020 20:47:39 +0000 (23:47 +0300)
We share interp_in wrappers for different types of signatures if the corresponding params are equivalent. This was added in https://github.com/mono/mono/commit/5cbe93884798684efbb81abd79e0e2a170544b75. This was reusing some sharing mechanism used by gsharedvt. Those wrappers are shared with regard to managed->managed transitions so it takes additional freedoms, converting all valuetypes to ValueTuples instances. These can end up being marshalled differently from the initial struct so we can't use this valuetype sharing infrastructure in the interp_in_wrappers which can operate on native structs.

Fixes test_0_marshal_struct_delegate from pinvoke3.cs

Co-authored-by: BrzVlad <BrzVlad@users.noreply.github.com>
src/mono/mono/mini/mini-generic-sharing.c

index 9bf9c2c..23a7028 100644 (file)
@@ -1335,8 +1335,10 @@ get_wrapper_shared_type (MonoType *t)
 
 /* Returns the intptr type for types that are passed in a single register */
 static MonoType*
-get_wrapper_shared_type_reg (MonoType *t)
+get_wrapper_shared_type_reg (MonoType *t, gboolean pinvoke)
 {
+       MonoType *orig_t = t;
+
        t = get_wrapper_shared_type (t);
        if (t->byref)
                return t;
@@ -1364,6 +1366,15 @@ get_wrapper_shared_type_reg (MonoType *t)
        case MONO_TYPE_ARRAY:
        case MONO_TYPE_PTR:
                return mono_get_int_type ();
+       case MONO_TYPE_GENERICINST:
+               if (orig_t->type == MONO_TYPE_VALUETYPE && pinvoke)
+                       /*
+                        * These are translated to instances of Mono.ValueTuple, but generic types
+                        * cannot be passed in pinvoke.
+                        */
+                       return orig_t;
+               else
+                       return t;
        default:
                return t;
        }
@@ -1375,9 +1386,9 @@ mini_get_underlying_reg_signature (MonoMethodSignature *sig)
        MonoMethodSignature *res = mono_metadata_signature_dup (sig);
        int i;
 
-       res->ret = get_wrapper_shared_type_reg (sig->ret);
+       res->ret = get_wrapper_shared_type_reg (sig->ret, sig->pinvoke);
        for (i = 0; i < sig->param_count; ++i)
-               res->params [i] = get_wrapper_shared_type_reg (sig->params [i]);
+               res->params [i] = get_wrapper_shared_type_reg (sig->params [i], sig->pinvoke);
        res->generic_param_count = 0;
        res->is_inflated = 0;