[runtime] Fix non-byref LPArray marshalling. Fixes #36128.
authorZoltan Varga <vargaz@gmail.com>
Sun, 22 Nov 2015 14:04:18 +0000 (09:04 -0500)
committerZoltan Varga <vargaz@gmail.com>
Sun, 22 Nov 2015 14:04:21 +0000 (09:04 -0500)
mono/metadata/marshal.c
mono/tests/libtest.c
mono/tests/pinvoke2.cs

index d09c52dc46f0e2f44abe9270698758d1d1db8aff..0e2d8fb628593ed39aa6d3808623ea877d502dcc 100644 (file)
@@ -6123,17 +6123,19 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                break;
                        }
 
-                       mono_mb_emit_ldarg (mb, argnum);
+                       if (t->byref ) {
+                               mono_mb_emit_ldarg (mb, argnum);
 
-                       /* Create the managed array */
-                       mono_mb_emit_ldarg (mb, param_num);
-                       if (m->sig->params [param_num]->byref)
-                               // FIXME: Support other types
-                               mono_mb_emit_byte (mb, CEE_LDIND_I4);
-                       mono_mb_emit_byte (mb, CEE_CONV_OVF_I);
-                       mono_mb_emit_op (mb, CEE_NEWARR, klass->element_class);
-                       /* Store into argument */
-                       mono_mb_emit_byte (mb, CEE_STIND_I);
+                               /* Create the managed array */
+                               mono_mb_emit_ldarg (mb, param_num);
+                               if (m->sig->params [param_num]->byref)
+                                       // FIXME: Support other types
+                                       mono_mb_emit_byte (mb, CEE_LDIND_I4);
+                               mono_mb_emit_byte (mb, CEE_CONV_OVF_I);
+                               mono_mb_emit_op (mb, CEE_NEWARR, klass->element_class);
+                               /* Store into argument */
+                               mono_mb_emit_byte (mb, CEE_STIND_I);
+                       }
                }
 
                if (need_convert || need_free) {
index 7a6f7d1e17225cc62eeed3efcd415b61ed187eb9..60983ef323e4f863a97cdd7857158d20407a337c 100644 (file)
@@ -524,6 +524,19 @@ mono_test_marshal_out_byref_array_out_size_param (int **out_arr, int *out_len)
        return 0;
 }
 
+LIBTEST_API int STDCALL
+mono_test_marshal_out_lparray_out_size_param (int *arr, int *out_len)
+{
+       int i, len;
+
+       len = 4;
+       for (i = 0; i < len; ++i)
+               arr [i] = i;
+       *out_len = len;
+
+       return 0;
+}
+
 LIBTEST_API int STDCALL  
 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
 {
index d4d6bebd0db5b76eddf9fcf91acd1f9438413c99..cf87dbd103ebb573474156857868bb06f1522177 100644 (file)
@@ -234,6 +234,9 @@ public class Tests {
        [DllImport ("libtest", EntryPoint="mono_test_marshal_out_byref_array_out_size_param")]
        public static extern int mono_test_marshal_out_byref_array_out_size_param ([Out] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out int [] a1, out int n);
 
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_out_lparray_out_size_param")]
+       public static extern int mono_test_marshal_out_lparray_out_size_param ([Out] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int [] a1, out int n);
+
        [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_nonblittable_array", CharSet = CharSet.Unicode)]
        public static extern int mono_test_marshal_inout_nonblittable_array ([In, Out] char [] a1);
        
@@ -434,6 +437,22 @@ public class Tests {
                return 0;
        }
 
+       public static int test_0_marshal_out_lparray_out_size_param () {
+               int [] a1 = null;
+               int len;
+
+               a1 = new int [10];
+               int res = mono_test_marshal_out_lparray_out_size_param (a1, out len);
+               // Check that a1 was not overwritten
+               a1.GetHashCode ();
+               if (len != 4)
+                       return 1;
+               for (int i = 0; i < len; i++)
+                       if (a1 [i] != i)
+                               return 2;
+               return 0;
+       }
+
        public static int test_0_marshal_inout_nonblittable_array () {
                char [] a1 = new char [10];
                for (int i = 0; i < 10; i++)