From 574fc7635e75cc08306baaf4ddce8cb72177e4fe Mon Sep 17 00:00:00 2001 From: Manodasan Wignarajah Date: Tue, 5 Apr 2022 16:41:06 -0700 Subject: [PATCH] Fix boxing empty blittable arrays (#1158) * Fix boxing blittable empty arrays * Update testwinrt repo --- .../UnitTest/TestComponentCSharp_Tests.cs | 22 ++++++ src/Tests/UnitTest/TestComponent_Tests.cs | 68 +++++++++++++++++++ src/WinRT.Runtime/Marshalers.cs | 9 +++ src/get_testwinrt.cmd | 2 +- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs index e2ade8cdd..266c00e19 100644 --- a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs +++ b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs @@ -887,6 +887,28 @@ public void TestValueSet() { Assert.Equal(valueSet[item.Key], item.Value); } + } + + [Fact] + public void TestValueSetArrays() + { + var map = new Dictionary + { + ["foo"] = new long[] { 1, 2, 3 }, + ["hello"] = new long[0], + ["world"] = new long[] { 1, 2, 3 }, + ["bar"] = new long[0] + }; + var valueSet = new Windows.Foundation.Collections.ValueSet(); + foreach (var item in map) + { + valueSet[item.Key] = item.Value; + } + Assert.Equal(map.Count, valueSet.Count); + foreach (var item in map) + { + Assert.Equal(valueSet[item.Key], item.Value); + } } [Fact] diff --git a/src/Tests/UnitTest/TestComponent_Tests.cs b/src/Tests/UnitTest/TestComponent_Tests.cs index a493a3fc7..afc2d29f1 100644 --- a/src/Tests/UnitTest/TestComponent_Tests.cs +++ b/src/Tests/UnitTest/TestComponent_Tests.cs @@ -1085,6 +1085,74 @@ public void Box_DateTime() Box_type(DateTimeOffset.Now, Tests.Box17); } + [Fact] + public void Box_LongArray() + { + long[] arr = new long[] { 2, 4, 6 }; + Box_type(arr, Tests.Box18); + + long[] arr2 = new long[] { 2, 4, 6 }; + Box_type(arr2, Tests.Box18); + Box_type(arr2, Tests.Box18); + + long[] arr3 = new long[0]; + Box_type(arr3, Tests.Box18); + + long[] arr4 = new long[0]; + Box_type(arr4, Tests.Box18); + } + + [Fact] + public void Box_BoolArray() + { + bool[] arr = new bool[] { true, false, true }; + Box_type(arr, Tests.Box19); + + bool[] arr2 = new bool[] { true, false, true }; + Box_type(arr2, Tests.Box19); + Box_type(arr2, Tests.Box19); + + bool[] arr3 = new bool[0]; + Box_type(arr3, Tests.Box19); + + bool[] arr4 = new bool[0]; + Box_type(arr4, Tests.Box19); + } + + [Fact] + public void Box_StringArray() + { + string[] arr = new string[] { "one", "two", "three" }; + Box_type(arr, Tests.Box20); + + string[] arr2 = new string[] { "four", "five", "six" }; + Box_type(arr2, Tests.Box20); + Box_type(arr2, Tests.Box20); + + string[] arr3 = new string[0]; + Box_type(arr3, Tests.Box20); + + string[] arr4 = new string[0]; + Box_type(arr4, Tests.Box20); + } + + [Fact] + public void Box_TimeSpanArray() + { + TimeSpan[] arr = new TimeSpan[] { TimeSpan.FromMilliseconds(4), TimeSpan.FromMilliseconds(5), TimeSpan.FromMilliseconds(6) }; + Box_type(arr, Tests.Box21); + + TimeSpan[] arr2 = new TimeSpan[] { TimeSpan.FromMilliseconds(4), TimeSpan.FromMilliseconds(5), TimeSpan.FromMilliseconds(6) }; + Box_type(arr2, Tests.Box21); + Box_type(arr2, Tests.Box21); + + TimeSpan[] arr3 = new TimeSpan[0]; + Box_type(arr3, Tests.Box21); + + TimeSpan[] arr4 = new TimeSpan[0]; + Box_type(arr4, Tests.Box21); + } + [Fact] public void Fast_Abi_Simple() { diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index 8abafa290..dcb61f881 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -386,6 +386,15 @@ public static unsafe T[] FromAbiArray(object box) { return null; } + + // For empty arrays, we can end up returning the same managed object + // when using ReadOnlySpan.ToArray. But a unique object is expected + // by the caller for RCW creation. + if (abi.length == 0) + { + return new T[0]; + } + var abiSpan = new ReadOnlySpan(abi.data.ToPointer(), abi.length); return abiSpan.ToArray(); } diff --git a/src/get_testwinrt.cmd b/src/get_testwinrt.cmd index 222ef31e9..85b4a3586 100644 --- a/src/get_testwinrt.cmd +++ b/src/get_testwinrt.cmd @@ -14,7 +14,7 @@ git checkout -f master if ErrorLevel 1 popd & exit /b !ErrorLevel! git fetch -f if ErrorLevel 1 popd & exit /b !ErrorLevel! -git reset -q --hard 53e87ecb7dd2fc883062ea9d95296768b604f058 +git reset -q --hard d7acaf7d18d7902f7181ee094a27966b2b5b87f0 if ErrorLevel 1 popd & exit /b !ErrorLevel! echo Restoring Nuget %this_dir%.nuget\nuget.exe restore