Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLarry Ewing <lewing@microsoft.com>2022-04-16 02:55:38 +0300
committerGitHub <noreply@github.com>2022-04-16 02:55:38 +0300
commit1e81682d7eed05b5bcdda00f757f485bf8a02e80 (patch)
tree139defedcc2ec199d87ca42e06a9b837a565aa01 /src/tests/Loader
parentd386b72ef72192692b21abed1aaedda10edd2e1f (diff)
parent736883624a7ef175729cf082e12ce18f236d8524 (diff)
Merge branch 'main' into darc-main-31d4c308-6782-4440-8589-61f58f239059
Diffstat (limited to 'src/tests/Loader')
-rw-r--r--src/tests/Loader/classloader/generics/Pointers/Pointers.cs220
-rw-r--r--src/tests/Loader/classloader/generics/Pointers/Pointers.csproj12
2 files changed, 232 insertions, 0 deletions
diff --git a/src/tests/Loader/classloader/generics/Pointers/Pointers.cs b/src/tests/Loader/classloader/generics/Pointers/Pointers.cs
new file mode 100644
index 00000000000..99d1dc2e838
--- /dev/null
+++ b/src/tests/Loader/classloader/generics/Pointers/Pointers.cs
@@ -0,0 +1,220 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+using Xunit;
+
+unsafe class Pointers
+{
+ private struct Struct { public int Num; }
+
+ private class Test<T> where T : unmanaged
+ {
+ public T Pointer(T* pointer) => *pointer;
+
+ public T[] PointerArray(T*[] array)
+ {
+ T[] res = new T[array.Length];
+ for (int i = 0; i < array.Length; i++)
+ res[i] = *array[i];
+
+ return res;
+ }
+
+ public void FunctionPointer(delegate*<T, void> func) => func(default);
+
+ public void FunctionPointerArray(delegate*<T, void>[] array)
+ {
+ foreach (var func in array)
+ func(default);
+ }
+ }
+
+ private class TestTwoParams<T, U> where T : unmanaged where U : unmanaged
+ {
+ public (T, U) Pointer(T* pointer1, U* pointer2) => (*pointer1, *pointer2);
+
+ public (T[], U[]) PointerArray(T*[] array1, U*[] array2)
+ {
+ T[] res1 = new T[array1.Length];
+ for (int i = 0; i < array1.Length; i++)
+ res1[i] = *array1[i];
+
+ U[] res2 = new U[array2.Length];
+ for (int i = 0; i < array2.Length; i++)
+ res2[i] = *array2[i];
+
+ return (res1, res2);
+ }
+
+ public void FunctionPointer(delegate*<T, void> func1, delegate*<U, void> func2)
+ {
+ func1(default);
+ func2(default);
+ }
+
+ public void FunctionPointerArray(delegate*<T, void>[] array1, delegate*<U, void>[] array2)
+ {
+ foreach (var func in array1)
+ func(default);
+
+ foreach (var func in array2)
+ func(default);
+ }
+ }
+
+ [Fact]
+ public static void Pointer()
+ {
+ Console.WriteLine($"Validating {nameof(Pointer)}...");
+ PointerImpl();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void PointerImpl()
+ {
+ int i = 0;
+ Struct s = default;
+ {
+ var t = new Test<int>();
+ int res = t.Pointer(&i);
+ Assert.Equal(i, res);
+ }
+ {
+ var t = new Test<Struct>();
+ Struct res = t.Pointer(&s);
+ Assert.Equal(s, res);
+ }
+ {
+ var t = new TestTwoParams<int, Struct>();
+ (int res1, Struct res2) = t.Pointer(&i, &s);
+ Assert.Equal(i, res1);
+ Assert.Equal(s, res2);
+ }
+ }
+
+ [Fact]
+ public static void PointerArray()
+ {
+ Console.WriteLine($"Validating {nameof(PointerArray)}...");
+ PointerArrayImpl();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void PointerArrayImpl()
+ {
+ int*[] intPtrArray = new int*[5];
+ Span<int> intSpan = stackalloc int[intPtrArray.Length];
+ int* intArray = (int*)Unsafe.AsPointer(ref intSpan.GetPinnableReference());
+ for (int i = 0; i < intPtrArray.Length; i++)
+ {
+ intArray[i] = i;
+ intPtrArray[i] = &intArray[i];
+ }
+
+ Struct*[] structPtrArray = new Struct*[5];
+ Span<Struct> structSpan = stackalloc Struct[structPtrArray.Length];
+ Struct* structArray = (Struct*)Unsafe.AsPointer(ref structSpan.GetPinnableReference());
+ for (int i = 0; i < structPtrArray.Length; i++)
+ {
+ structArray[i] = new Struct() { Num = i };
+ structPtrArray[i] = &structArray[i];
+ }
+
+ {
+ var t = new Test<int>();
+ int[] res = t.PointerArray(intPtrArray);
+ Assert.True(intSpan.SequenceEqual(res));
+ }
+ {
+ var t = new Test<Struct>();
+ Struct[] res = t.PointerArray(structPtrArray);
+ Assert.True(structSpan.SequenceEqual(res));
+ }
+ {
+ var t = new TestTwoParams<int, Struct>();
+ (int[] res1, Struct[] res2) = t.PointerArray(intPtrArray, structPtrArray);
+ Assert.True(intSpan.SequenceEqual(res1));
+ Assert.True(structSpan.SequenceEqual(res2));
+ }
+ }
+
+ [Fact]
+ public static void FunctionPointer()
+ {
+ Console.WriteLine($"Validating {nameof(FunctionPointer)}...");
+ FunctionPointerImpl();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void FunctionPointerImpl()
+ {
+ s_takeIntCallCount = 0;
+ s_takeStructCallCount = 0;
+ {
+ var t = new Test<int>();
+ t.FunctionPointer(&TakeInt);
+ Assert.Equal(1, s_takeIntCallCount);
+ }
+ {
+ var t = new Test<Struct>();
+ t.FunctionPointer(&TakeStruct);
+ Assert.Equal(1, s_takeStructCallCount);
+ }
+ {
+ var t = new TestTwoParams<int, Struct>();
+ t.FunctionPointer(&TakeInt, &TakeStruct);
+ Assert.Equal(2, s_takeIntCallCount);
+ Assert.Equal(2, s_takeStructCallCount);
+ }
+
+ }
+
+ [Fact]
+ public static void FunctionPointerArray()
+ {
+ Console.WriteLine($"Validating {nameof(FunctionPointerArray)}...");
+ FunctionPointerArrayImpl();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void FunctionPointerArrayImpl()
+ {
+ int length = 5;
+ delegate*<int, void>[] intFuncArray = new delegate*<int, void>[length];
+ delegate*<Struct, void>[] structFuncArray = new delegate*<Struct, void>[length];
+ for (int i = 0; i < length; i++)
+ {
+ intFuncArray[i] = &TakeInt;
+ structFuncArray[i] = &TakeStruct;
+ }
+
+ s_takeIntCallCount = 0;
+ s_takeStructCallCount = 0;
+ {
+ var t = new Test<int>();
+ t.FunctionPointerArray(intFuncArray);
+ Assert.Equal(length, s_takeIntCallCount);
+ }
+ {
+ var t = new Test<Struct>();
+ t.FunctionPointerArray(structFuncArray);
+ Assert.Equal(length, s_takeStructCallCount);
+ }
+ {
+ var t = new TestTwoParams<int, Struct>();
+ t.FunctionPointerArray(intFuncArray, structFuncArray);
+ Assert.Equal(length * 2, s_takeIntCallCount);
+ Assert.Equal(length * 2, s_takeStructCallCount);
+ }
+ }
+
+ static int s_takeIntCallCount = 0;
+ private static void TakeInt(int _) => s_takeIntCallCount++;
+
+ static int s_takeStructCallCount = 0;
+ private static void TakeStruct(Struct _) => s_takeStructCallCount++;
+}
diff --git a/src/tests/Loader/classloader/generics/Pointers/Pointers.csproj b/src/tests/Loader/classloader/generics/Pointers/Pointers.csproj
new file mode 100644
index 00000000000..160aa059d73
--- /dev/null
+++ b/src/tests/Loader/classloader/generics/Pointers/Pointers.csproj
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Compile Include="Pointers.cs" />
+ </ItemGroup>
+
+</Project>