瀏覽代碼

[runtime] Fix non-byref LPArray marshalling. Fixes #36128.

Zoltan Varga 10 年之前
父節點
當前提交
a425ee9491
共有 3 個文件被更改,包括 44 次插入10 次删除
  1. 12 10
      mono/metadata/marshal.c
  2. 13 0
      mono/tests/libtest.c
  3. 19 0
      mono/tests/pinvoke2.cs

+ 12 - 10
mono/metadata/marshal.c

@@ -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) {

+ 13 - 0
mono/tests/libtest.c

@@ -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)
 {

+ 19 - 0
mono/tests/pinvoke2.cs

@@ -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++)