From 102420497169bceaaf76f9502f395fd6f359a91e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 28 Jan 2025 23:37:26 -0800 Subject: [PATCH 01/18] Disable 'Marshaler' on AOT --- src/WinRT.Runtime/Marshalers.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index b5df5fbadf..ebac586657 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -2044,6 +2044,15 @@ class Marshaler { static Marshaler() { +#if NET + if (!RuntimeFeature.IsDynamicCodeCompiled) + { + throw new NotSupportedException( + $"'Marshaler' is not supported in AOT environments, and is only supported for backwards compatibility in JIT environments. " + + $"The type '{typeof(T)}' cannot be marshalled using it. Consider using the appropriate, more specific marshaller type instead."); + } +#endif + // Structs cannot contain arrays, and arrays may only ever appear as parameters if (typeof(T).IsArray) { From 5093d201a06ae8fed4d042a5f856379fc84e5e88 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 28 Jan 2025 23:38:33 -0800 Subject: [PATCH 02/18] Update 'AsAgile' extension --- src/WinRT.Runtime/CastExtensions.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/WinRT.Runtime/CastExtensions.cs b/src/WinRT.Runtime/CastExtensions.cs index cc12b1a288..a8a120b82e 100644 --- a/src/WinRT.Runtime/CastExtensions.cs +++ b/src/WinRT.Runtime/CastExtensions.cs @@ -94,23 +94,15 @@ public static AgileReference AsAgile(this T value) where T : class return new AgileReference(null); } - var marshal = Marshaler.CreateMarshaler2(value); + var objrefValue = MarshalInspectable.CreateMarshaler2(value); try { - if (marshal is IObjectReference objref) - { - return new AgileReference(objref); - } - else if (marshal is ObjectReferenceValue objrefValue) - { - return new AgileReference(objrefValue); - } + return new AgileReference(objrefValue); } finally { - Marshaler.DisposeMarshaler(marshal); + objrefValue.Dispose(); } - throw new InvalidOperationException($"Object type is not a projected type: {nameof(value)}."); } private static bool TryGetRefForObject(object value, bool allowComposed, out IObjectReference reference) From af9359658f3c485d1e06e8ab13281ffd1226930d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 28 Jan 2025 23:51:45 -0800 Subject: [PATCH 03/18] Update 'StructTypeDetails<,>.GetNullableValue' --- src/WinRT.Runtime/Projections/Nullable.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/WinRT.Runtime/Projections/Nullable.cs b/src/WinRT.Runtime/Projections/Nullable.cs index c912fcc0a0..427ea4f44a 100644 --- a/src/WinRT.Runtime/Projections/Nullable.cs +++ b/src/WinRT.Runtime/Projections/Nullable.cs @@ -2421,18 +2421,27 @@ unsafe object IWinRTNullableTypeDetails.GetNullableValue(IInspectable inspectabl { ExceptionHelpers.ThrowExceptionForHR(Marshal.QueryInterface(inspectable.ThisPtr, ref Unsafe.AsRef(in PIID), out nullablePtr)); ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)nullablePtr)[6](nullablePtr, &__retval)); + if (typeof(T) == typeof(TAbi)) { return __retval; } else { - return Marshaler.FromAbi(__retval); + // If 'typeof(T) != typeof(TAbi)', then we know the type is not blittable. + // We can use the specific marshaller then to minimize binary size here. + return MarshalNonBlittable.FromAbi(__retval); } } finally { - Marshaler.DisposeAbi(__retval); + // We only need to dispose in the non blittable case. Otherwise, + // that value is returned directly to the caller and used as is. + if (typeof(T) != typeof(TAbi)) + { + MarshalNonBlittable.DisposeAbi(__retval); + } + MarshalExtensions.ReleaseIfNotNull(nullablePtr); } } @@ -2491,11 +2500,11 @@ unsafe object IWinRTNullableTypeDetails.GetNullableValue(IInspectable inspectabl { ExceptionHelpers.ThrowExceptionForHR(Marshal.QueryInterface(inspectable.ThisPtr, ref Unsafe.AsRef(in PIID), out nullablePtr)); ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)nullablePtr)[6](nullablePtr, &__retval)); - return new ABI.System.Nullable(Marshaler.FromAbi(__retval)); + return new ABI.System.Nullable(MarshalDelegate.FromAbi(__retval)); } finally { - Marshaler.DisposeAbi(__retval); + MarshalExtensions.ReleaseIfNotNull(__retval); MarshalExtensions.ReleaseIfNotNull(nullablePtr); } } From dfb78719b36dc8b22e9414e3a7b31ceb61e36180 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jan 2025 09:23:08 -0800 Subject: [PATCH 04/18] Add AOT annotations for 'Marshaler' changes --- src/WinRT.Runtime/AttributeMessages.net5.cs | 5 ++ src/WinRT.Runtime/Marshalers.cs | 5 ++ src/WinRT.Runtime/Projections/EventHandler.cs | 6 +- .../Projections/IDictionary.net5.cs | 28 +++++-- .../Projections/IEnumerable.net5.cs | 22 ++++- src/WinRT.Runtime/Projections/IList.net5.cs | 84 ++++++++++++------- .../Projections/IReadOnlyDictionary.net5.cs | 26 +++--- .../Projections/IReadOnlyList.net5.cs | 24 ++++-- src/WinRT.Runtime/Projections/KeyValuePair.cs | 21 ++++- src/WinRT.Runtime/Projections/Nullable.cs | 11 ++- 10 files changed, 170 insertions(+), 62 deletions(-) diff --git a/src/WinRT.Runtime/AttributeMessages.net5.cs b/src/WinRT.Runtime/AttributeMessages.net5.cs index 04eda9fa34..ad9509af89 100644 --- a/src/WinRT.Runtime/AttributeMessages.net5.cs +++ b/src/WinRT.Runtime/AttributeMessages.net5.cs @@ -20,6 +20,11 @@ internal static class AttributeMessages /// public const string MarshallingOrGenericInstantiationsRequiresDynamicCode = "The necessary marshalling code or generic instantiations might not be available."; + /// + /// Message for APIs not supported when dynamic code is not available (ie. in AOT environments). + /// + public const string NotSupportedIfDynamicCodeIsNotAvailable = "The annotated API is not supported when dynamic code is not available (ie. in AOT environments)."; + /// /// Message for suppressing trim warnings for calls with ABI types as type arguments for constrained type parameters. /// diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index ebac586657..4f35ee3415 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; @@ -2035,6 +2036,10 @@ internal static class Marshaler private static unsafe void CopyUIntEnumDirect(object value, IntPtr dest) => *(uint*)dest.ToPointer() = (uint)value; } +#if NET + [EditorBrowsable(EditorBrowsableState.Never)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif #if EMBED internal #else diff --git a/src/WinRT.Runtime/Projections/EventHandler.cs b/src/WinRT.Runtime/Projections/EventHandler.cs index 0beec1abea..d6fcd3fc92 100644 --- a/src/WinRT.Runtime/Projections/EventHandler.cs +++ b/src/WinRT.Runtime/Projections/EventHandler.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Concurrent; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -242,7 +243,6 @@ public unsafe void Invoke(object sender, T args) IntPtr ThisPtr = _nativeDelegate.ThisPtr; var abiInvoke = Marshal.GetDelegateForFunctionPointer(_nativeDelegate.Vftbl.Invoke, _abi_invoke_type); -#pragma warning restore IL3050 ObjectReferenceValue __sender = default; object __args = default; var __params = new object[] { ThisPtr, null, null }; @@ -262,6 +262,7 @@ public unsafe void Invoke(object sender, T args) Marshaler.DisposeMarshaler(__args); } } +#pragma warning restore IL3050 } } @@ -280,6 +281,9 @@ public static IntPtr FromManaged(global::System.EventHandler managedDelegate) public static void DisposeMarshalerArray(MarshalInterfaceHelper>.MarshalerArray array) => MarshalInterfaceHelper>.DisposeMarshalerArray(array); public static unsafe void DisposeAbiArray(object box) => MarshalInspectable.DisposeAbiArray(box); +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_Invoke(void* thisPtr, IntPtr sender, TAbi args) { try diff --git a/src/WinRT.Runtime/Projections/IDictionary.net5.cs b/src/WinRT.Runtime/Projections/IDictionary.net5.cs index f9f38cbe02..afdd8581e1 100644 --- a/src/WinRT.Runtime/Projections/IDictionary.net5.cs +++ b/src/WinRT.Runtime/Projections/IDictionary.net5.cs @@ -296,7 +296,7 @@ unsafe static IDictionaryMethods() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] @@ -769,7 +769,7 @@ public unsafe static bool InitRcwHelper( } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private unsafe static bool InitRcwHelperFallback() { @@ -782,7 +782,7 @@ private unsafe static bool InitRcwHelperFallback() } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe V LookupDynamic(IObjectReference obj, K key) { @@ -807,7 +807,7 @@ private static unsafe V LookupDynamic(IObjectReference obj, K key) } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe bool HasKeyDynamic(IObjectReference obj, K key) { @@ -831,7 +831,7 @@ private static unsafe bool HasKeyDynamic(IObjectReference obj, K key) } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe bool InsertDynamic(IObjectReference obj, K key, V value) { @@ -859,7 +859,7 @@ private static unsafe bool InsertDynamic(IObjectReference obj, K key, V value) } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe void RemoveDynamic(IObjectReference obj, K key) { @@ -919,7 +919,7 @@ public static unsafe bool InitCcw( private static global::System.Delegate[] DelegateCache; #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif internal static unsafe void InitFallbackCCWVtable() { @@ -945,6 +945,9 @@ internal static unsafe void InitFallbackCCWVtable() ); } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_Lookup_0(void* thisPtr, KAbi key, VAbi* __return_value__) { V ____return_value__ = default; @@ -964,6 +967,9 @@ private static unsafe int Do_Abi_Lookup_0(void* thisPtr, KAbi key, VAbi* __retur return 0; } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_HasKey_2(void* thisPtr, KAbi key, byte* __return_value__) { bool ____return_value__ = default; @@ -1003,6 +1009,9 @@ private static unsafe int Do_Abi_GetView_3(IntPtr thisPtr, IntPtr* __return_valu return 0; } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_Insert_4(void* thisPtr, KAbi key, VAbi value, byte* __return_value__) { bool ____return_value__ = default; @@ -1022,6 +1031,9 @@ private static unsafe int Do_Abi_Insert_4(void* thisPtr, KAbi key, VAbi value, b return 0; } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_Remove_5(void* thisPtr, KAbi key) { try @@ -1296,7 +1308,7 @@ static IDictionary() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] diff --git a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs index db2b85c68d..f0ad6f216c 100644 --- a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs +++ b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs @@ -417,7 +417,7 @@ static IEnumerable() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] @@ -548,6 +548,7 @@ public static unsafe uint GetMany(IObjectReference obj, ref T[] items) int __items_length = default; IntPtr __items_data = default; uint __retval = default; +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 try { __items = Marshaler.CreateMarshalerArray(items); @@ -561,6 +562,7 @@ public static unsafe uint GetMany(IObjectReference obj, ref T[] items) { Marshaler.DisposeMarshalerArray(__items); } +#pragma warning restore IL3050 } } @@ -603,7 +605,7 @@ unsafe static IEnumeratorMethods() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] @@ -703,11 +705,17 @@ public unsafe static bool InitRcwHelper( return true; } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private unsafe static bool InitRcwHelperFallback() { return InitRcwHelper(&get_Current, null); } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private unsafe static T get_Current(IObjectReference obj) { var ThisPtr = obj.ThisPtr; @@ -754,7 +762,7 @@ public static unsafe bool InitCcw( private static global::System.Delegate[] DelegateCache; #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif internal static unsafe void InitFallbackCCWVtable() { @@ -796,6 +804,9 @@ private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* __return_value return 0; } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* __return_value__) { uint ____return_value__ = default; @@ -818,6 +829,9 @@ private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntP return 0; } +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, TAbi* __return_value__) { T ____return_value__ = default; @@ -1161,7 +1175,7 @@ static IEnumerator() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] diff --git a/src/WinRT.Runtime/Projections/IList.net5.cs b/src/WinRT.Runtime/Projections/IList.net5.cs index c58620042f..1310f9f2dc 100644 --- a/src/WinRT.Runtime/Projections/IList.net5.cs +++ b/src/WinRT.Runtime/Projections/IList.net5.cs @@ -173,7 +173,7 @@ unsafe static IListMethods() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] @@ -489,7 +489,7 @@ public unsafe static bool InitRcwHelper( } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private unsafe static bool InitRcwHelperFallback() { @@ -502,8 +502,11 @@ private unsafe static bool InitRcwHelperFallback() &AppendDynamic, null, null); - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe T GetAtDynamic(IObjectReference obj, uint index) { var ThisPtr = obj.ThisPtr; @@ -521,7 +524,7 @@ private static unsafe T GetAtDynamic(IObjectReference obj, uint index) } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe bool IndexOfDynamic(IObjectReference obj, T value, out uint index) { @@ -547,7 +550,7 @@ private static unsafe bool IndexOfDynamic(IObjectReference obj, T value, out uin } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe void SetAtDynamic(IObjectReference obj, uint index, T value) { @@ -569,7 +572,7 @@ private static unsafe void SetAtDynamic(IObjectReference obj, uint index, T valu } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe void InsertAtDynamic(IObjectReference obj, uint index, T value) { @@ -591,7 +594,7 @@ private static unsafe void InsertAtDynamic(IObjectReference obj, uint index, T v } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe void AppendDynamic(IObjectReference obj, T value) { @@ -660,7 +663,7 @@ public static unsafe bool InitCcw( private static global::System.Delegate[] DelegateCache; #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif internal static unsafe void InitFallbackCCWVtable() { @@ -696,8 +699,11 @@ internal static unsafe void InitFallbackCCWVtable() (delegate* unmanaged[Stdcall])Marshal.GetFunctionPointerForDelegate(DelegateCache[10]), (delegate* unmanaged[Stdcall])Marshal.GetFunctionPointerForDelegate(DelegateCache[11]) ); - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_GetAt_0(void* thisPtr, uint index, TAbi* __return_value__) { T ____return_value__ = default; @@ -731,8 +737,11 @@ private static unsafe int Do_Abi_GetView_2(IntPtr thisPtr, IntPtr* __return_valu return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_IndexOf_3(void* thisPtr, TAbi value, uint* index, byte* __return_value__) { bool ____return_value__ = default; @@ -753,8 +762,11 @@ private static unsafe int Do_Abi_IndexOf_3(void* thisPtr, TAbi value, uint* inde return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_SetAt_4(void* thisPtr, uint index, TAbi value) { try @@ -767,8 +779,11 @@ private static unsafe int Do_Abi_SetAt_4(void* thisPtr, uint index, TAbi value) return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_InsertAt_5(void* thisPtr, uint index, TAbi value) { try @@ -795,8 +810,11 @@ private static unsafe int Do_Abi_RemoveAt_6(IntPtr thisPtr, uint index) return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_Append_7(void* thisPtr, TAbi value) { try @@ -837,8 +855,11 @@ private static unsafe int Do_Abi_Clear_9(IntPtr thisPtr) return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_GetMany_10(IntPtr thisPtr, uint startIndex, int __itemsSize, IntPtr items, uint* __return_value__) { uint ____return_value__ = default; @@ -859,8 +880,11 @@ private static unsafe int Do_Abi_GetMany_10(IntPtr thisPtr, uint startIndex, int return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_ReplaceAll_11(IntPtr thisPtr, int __itemsSize, IntPtr items) { try @@ -1131,7 +1155,8 @@ public static unsafe uint GetMany(IObjectReference obj, uint startIndex, ref T[] object __items = default; int __items_length = default; IntPtr __items_data = default; - uint __retval = default; + uint __retval = default; +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 try { __items = Marshaler.CreateMarshalerArray(items); @@ -1144,7 +1169,8 @@ public static unsafe uint GetMany(IObjectReference obj, uint startIndex, ref T[] finally { Marshaler.DisposeMarshalerArray(__items); - } + } +#pragma warning restore IL3050 } } @@ -1169,7 +1195,8 @@ public static unsafe void ReplaceAll(IObjectReference obj, T[] items) var ThisPtr = obj.ThisPtr; object __items = default; int __items_length = default; - IntPtr __items_data = default; + IntPtr __items_data = default; +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 try { __items = Marshaler.CreateMarshalerArray(items); @@ -1180,7 +1207,8 @@ public static unsafe void ReplaceAll(IObjectReference obj, T[] items) finally { Marshaler.DisposeMarshalerArray(__items); - } + } +#pragma warning restore IL3050 } } } @@ -1409,7 +1437,7 @@ static IList() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] diff --git a/src/WinRT.Runtime/Projections/IReadOnlyDictionary.net5.cs b/src/WinRT.Runtime/Projections/IReadOnlyDictionary.net5.cs index a63def4f7e..f3951c3616 100644 --- a/src/WinRT.Runtime/Projections/IReadOnlyDictionary.net5.cs +++ b/src/WinRT.Runtime/Projections/IReadOnlyDictionary.net5.cs @@ -225,7 +225,7 @@ unsafe static IReadOnlyDictionaryMethods() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] @@ -510,7 +510,7 @@ public unsafe static bool InitRcwHelper( } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private unsafe static bool InitRcwHelperFallback() { @@ -518,7 +518,7 @@ private unsafe static bool InitRcwHelperFallback() } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe V LookupDynamic(IObjectReference obj, K key) { @@ -543,7 +543,7 @@ private static unsafe V LookupDynamic(IObjectReference obj, K key) } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe bool HasKeyDynamic(IObjectReference obj, K key) { @@ -596,7 +596,7 @@ public static unsafe bool InitCcw( private static global::System.Delegate[] DelegateCache; #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif internal static unsafe void InitFallbackCCWVtable() { @@ -614,8 +614,11 @@ internal static unsafe void InitFallbackCCWVtable() (delegate* unmanaged[Stdcall])Marshal.GetFunctionPointerForDelegate(DelegateCache[2]), (delegate* unmanaged[Stdcall])Marshal.GetFunctionPointerForDelegate(DelegateCache[3]) ); - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_Lookup_0(IntPtr thisPtr, KAbi key, VAbi* __return_value__) { V ____return_value__ = default; @@ -633,8 +636,11 @@ private static unsafe int Do_Abi_Lookup_0(IntPtr thisPtr, KAbi key, VAbi* __retu return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - + } + +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_HasKey_2(IntPtr thisPtr, KAbi key, byte* __return_value__) { bool ____return_value__ = default; @@ -1119,7 +1125,7 @@ static IReadOnlyDictionary() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] diff --git a/src/WinRT.Runtime/Projections/IReadOnlyList.net5.cs b/src/WinRT.Runtime/Projections/IReadOnlyList.net5.cs index 185c70acde..7e38a4be08 100644 --- a/src/WinRT.Runtime/Projections/IReadOnlyList.net5.cs +++ b/src/WinRT.Runtime/Projections/IReadOnlyList.net5.cs @@ -110,7 +110,7 @@ internal static unsafe void EnsureInitialized() #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] @@ -191,6 +191,7 @@ public static unsafe uint GetMany(IObjectReference obj, uint startIndex, ref T[] int __items_length = default; IntPtr __items_data = default; uint __retval = default; +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 try { __items = Marshaler.CreateMarshalerArray(items); @@ -204,6 +205,7 @@ public static unsafe uint GetMany(IObjectReference obj, uint startIndex, ref T[] { Marshaler.DisposeMarshalerArray(__items); } +#pragma warning restore IL3050 } } } @@ -319,13 +321,16 @@ public unsafe static bool InitRcwHelper( } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private unsafe static bool InitRcwHelperFallback() { return InitRcwHelper(&GetAtDynamic, &IndexOfDynamic, null); } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private unsafe static T GetAtDynamic(IObjectReference obj, uint index) { var ThisPtr = obj.ThisPtr; @@ -343,7 +348,7 @@ private unsafe static T GetAtDynamic(IObjectReference obj, uint index) } #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif private static unsafe bool IndexOfDynamic(IObjectReference obj, T value, out uint index) { @@ -398,7 +403,7 @@ public static unsafe bool InitCcw( private static global::System.Delegate[] DelegateCache; #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif internal static unsafe void InitFallbackCCWVtable() { @@ -420,6 +425,9 @@ internal static unsafe void InitFallbackCCWVtable() ); } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, TAbi* __return_value__) { T ____return_value__ = default; @@ -438,6 +446,9 @@ private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, TAbi* __ret return 0; } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, TAbi value, uint* index, byte* __return_value__) { bool ____return_value__ = default; @@ -461,6 +472,9 @@ private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, TAbi value, uint* ind return 0; } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, uint startIndex, int __itemsSize, IntPtr items, uint* __return_value__) { uint ____return_value__ = default; @@ -661,7 +675,7 @@ static IReadOnlyList() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] diff --git a/src/WinRT.Runtime/Projections/KeyValuePair.cs b/src/WinRT.Runtime/Projections/KeyValuePair.cs index a36b22423d..cfd623647e 100644 --- a/src/WinRT.Runtime/Projections/KeyValuePair.cs +++ b/src/WinRT.Runtime/Projections/KeyValuePair.cs @@ -76,7 +76,7 @@ static void ThrowNotInitialized() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] @@ -159,11 +159,17 @@ public unsafe static bool InitRcwHelper( return true; } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private unsafe static bool InitRcwHelperFallback() { return InitRcwHelper(&get_Key, &get_Value); } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe K get_Key(IObjectReference obj) { var ThisPtr = obj.ThisPtr; @@ -180,6 +186,9 @@ private static unsafe K get_Key(IObjectReference obj) } } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe V get_Value(IObjectReference obj) { var ThisPtr = obj.ThisPtr; @@ -235,7 +244,7 @@ public static unsafe bool InitCcw( private static global::System.Delegate[] DelegateCache; #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif internal static unsafe void InitFallbackCCWVtable() { @@ -256,6 +265,9 @@ internal static unsafe void InitFallbackCCWVtable() ); } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_get_Key_0(IntPtr thisPtr, KAbi* __return_value__) { K ____return_value__ = default; @@ -273,6 +285,9 @@ private static unsafe int Do_Abi_get_Key_0(IntPtr thisPtr, KAbi* __return_value_ return 0; } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_get_Value_1(IntPtr thisPtr, VAbi* __return_value__) { V ____return_value__ = default; @@ -406,7 +421,7 @@ static KeyValuePair() #pragma warning restore IL3050 #if NET8_0_OR_GREATER - [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if NET [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = AttributeMessages.AbiTypesNeverHaveConstructors)] diff --git a/src/WinRT.Runtime/Projections/Nullable.cs b/src/WinRT.Runtime/Projections/Nullable.cs index 427ea4f44a..d5341da5b2 100644 --- a/src/WinRT.Runtime/Projections/Nullable.cs +++ b/src/WinRT.Runtime/Projections/Nullable.cs @@ -89,6 +89,9 @@ private static unsafe int Do_Abi_get_Value_0_DateTimeOffset(void* thisPtr, globa } } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif private static unsafe int Do_Abi_get_Value_0(void* thisPtr, out TAbi __return_value__) { T ____return_value__ = default; @@ -470,6 +473,7 @@ private static unsafe T GetValueFromAbi(IntPtr thisPtr, Delegate marshallingDele #endif { var __params = new object[] { thisPtr, null }; +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 try { marshallingDelegate.DynamicInvokeAbi(__params); @@ -479,6 +483,7 @@ private static unsafe T GetValueFromAbi(IntPtr thisPtr, Delegate marshallingDele { Marshaler.DisposeAbi(__params[1]); } +#pragma warning restore IL3050 } throw new NotSupportedException($"Cannot retrieve the value for the current Nullable`1 instance with type '{typeof(T)}'."); @@ -1992,7 +1997,7 @@ private static unsafe int Do_Abi_get_Value_0(IntPtr thisPtr, IntPtr* __return_va try { ____return_value__ = global::WinRT.ComWrappersSupport.FindObject(thisPtr); - *__return_value__ = (IntPtr)Marshaler.FromManaged(____return_value__); + *__return_value__ = (IntPtr)MarshalGeneric.FromManaged(____return_value__); } catch (global::System.Exception __exception__) { @@ -2018,11 +2023,11 @@ public static unsafe Nullable GetValue(IInspectable inspectable) #endif ); ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)nullablePtr)[6](nullablePtr, &__retval)); - return new Nullable(Marshaler.FromAbi(__retval)); + return new Nullable(MarshalDelegate.FromAbi(__retval)); } finally { - Marshaler.DisposeAbi(__retval); + MarshalExtensions.ReleaseIfNotNull(__retval); MarshalExtensions.ReleaseIfNotNull(nullablePtr); } } From 6bc7d1b2cf8e5f18c8044a174ff3dd2f8cc50334 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jan 2025 09:25:32 -0800 Subject: [PATCH 05/18] Update non blittable 'BoxedValueIReferenceImpl<,>' --- src/WinRT.Runtime/Projections/Nullable.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/WinRT.Runtime/Projections/Nullable.cs b/src/WinRT.Runtime/Projections/Nullable.cs index d5341da5b2..470fd8ba26 100644 --- a/src/WinRT.Runtime/Projections/Nullable.cs +++ b/src/WinRT.Runtime/Projections/Nullable.cs @@ -179,7 +179,9 @@ internal static unsafe Delegate GetValueDelegateForAbi(out IntPtr nativePtr) } } - internal static class BoxedValueIReferenceImpl where TAbi : unmanaged + internal static class BoxedValueIReferenceImpl + where T : struct + where TAbi : unmanaged { public static IntPtr AbiToProjectionVftablePtr; private static readonly global::ABI.System.Nullable_Delegates.GetValueDelegateAbi GetValue; @@ -207,7 +209,7 @@ private static unsafe int Do_Abi_get_Value_0(void* thisPtr, void* __return_value try { T ____return_value__ = (T)global::WinRT.ComWrappersSupport.FindObject(new IntPtr(thisPtr)); - *(TAbi*)__return_value__ = (TAbi)Marshaler.FromManaged(____return_value__); + *(TAbi*)__return_value__ = (TAbi)MarshalNonBlittable.FromManaged(____return_value__); } catch (global::System.Exception __exception__) { @@ -2390,7 +2392,9 @@ internal interface IWinRTNullableTypeDetails Type GetNullableType(); } - public sealed class StructTypeDetails : IWinRTExposedTypeDetails, IWinRTNullableTypeDetails where T: struct where TAbi : unmanaged + public sealed class StructTypeDetails : IWinRTExposedTypeDetails, IWinRTNullableTypeDetails + where T: struct + where TAbi : unmanaged { private static readonly Guid PIID = ABI.System.Nullable.PIID; From c5573c114eec3c1231c16aa78b882a01bdd30447 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jan 2025 09:41:47 -0800 Subject: [PATCH 06/18] Update 'BoxedArrayIReferenceArrayImpl' --- .../Projections/IReferenceArray.net5.cs | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs index b88bbf79e3..4766bdbead 100644 --- a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs +++ b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs @@ -46,7 +46,7 @@ private static unsafe int Do_Abi_get_Value_0(IntPtr thisPtr, int* ____return_val try { ____return_value__ = (T[])global::WinRT.ComWrappersSupport.FindObject(thisPtr); - (*____return_value__Size, *__return_value__) = Marshaler.FromManagedArray(____return_value__); + (*____return_value__Size, *__return_value__) = FromManagedArray(____return_value__); } catch (global::System.Exception __exception__) { @@ -55,6 +55,56 @@ private static unsafe int Do_Abi_get_Value_0(IntPtr thisPtr, int* ____return_val } return 0; } + + private static (int, IntPtr) FromManagedArray(T[] items) + { + // Blittable value types + if (typeof(T) == typeof(byte) || + typeof(T) == typeof(short) || + typeof(T) == typeof(ushort) || + typeof(T) == typeof(long) || + typeof(T) == typeof(ulong) || + typeof(T) == typeof(int) || + typeof(T) == typeof(uint) || + typeof(T) == typeof(float) || + typeof(T) == typeof(double) || + typeof(T) == typeof(Guid) || + typeof(T) == typeof(global::System.Numerics.Vector2) || + typeof(T) == typeof(global::System.Numerics.Vector3) || + typeof(T) == typeof(global::System.Numerics.Vector4) || + typeof(T) == typeof(global::System.Numerics.Quaternion) || + typeof(T) == typeof(global::System.Numerics.Plane) || + typeof(T) == typeof(global::System.Numerics.Matrix3x2) || + typeof(T) == typeof(global::System.Numerics.Matrix4x4)) + { + return MarshalBlittable.FromManagedArray(items); + } + + // Non-blittable value types + if (typeof(T) == typeof(bool) || + typeof(T) == typeof(char) || + typeof(T) == typeof(TimeSpan) || + typeof(T) == typeof(DateTimeOffset)) + { + return MarshalNonBlittable.FromManagedArray(items); + } + + // Other well-known reference types + if (typeof(T) == typeof(string)) return MarshalString.FromManagedArray(Unsafe.As(items)); + if (typeof(T) == typeof(Type)) return ABI.System.Type.FromManagedArray(Unsafe.As(items)); + if (typeof(T) == typeof(Exception)) return MarshalNonBlittable.FromManagedArray(Unsafe.As(items)); + if (typeof(T) == typeof(object)) return MarshalInspectable.FromManagedArray(Unsafe.As(items)); + +#if NET + if (!RuntimeFeature.IsDynamicCodeCompiled) + { + throw new NotSupportedException($"Support for 'IReferenceArray' for type '{typeof(T)}' is not available in AOT environments."); + } +#endif +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 + return Marshaler.FromManagedArray(items); +#pragma warning restore IL3050 + } } [Guid("61C17707-2D65-11E0-9AE8-D48564015472")] From 96f2aa4e8a046b82c3e967d105dfbf9d73c68955 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jan 2025 14:27:23 -0800 Subject: [PATCH 07/18] Normalize whitespaces --- src/WinRT.Runtime/ComWrappersSupport.net5.cs | 586 ++-- .../Projections/IPropertyValue.net5.cs | 2554 ++++++++--------- 2 files changed, 1570 insertions(+), 1570 deletions(-) diff --git a/src/WinRT.Runtime/ComWrappersSupport.net5.cs b/src/WinRT.Runtime/ComWrappersSupport.net5.cs index 06e0f973c5..d144f385f9 100644 --- a/src/WinRT.Runtime/ComWrappersSupport.net5.cs +++ b/src/WinRT.Runtime/ComWrappersSupport.net5.cs @@ -1,53 +1,53 @@ // Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Concurrent; +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT.Interop; -using static System.Runtime.InteropServices.ComWrappers; - -namespace WinRT -{ -#if EMBED - internal -#else - public -#endif - static partial class ComWrappersSupport - { - // Instance field and property for Singleton pattern: ComWrappers `set` method should be idempotent - private static DefaultComWrappers _instance; - private static DefaultComWrappers DefaultComWrappersInstance - { - get - { - if (_instance == null) - { - _instance = new DefaultComWrappers(); - } - return _instance; - } - } - +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT.Interop; +using static System.Runtime.InteropServices.ComWrappers; + +namespace WinRT +{ +#if EMBED + internal +#else + public +#endif + static partial class ComWrappersSupport + { + // Instance field and property for Singleton pattern: ComWrappers `set` method should be idempotent + private static DefaultComWrappers _instance; + private static DefaultComWrappers DefaultComWrappersInstance + { + get + { + if (_instance == null) + { + _instance = new DefaultComWrappers(); + } + return _instance; + } + } + internal static readonly ConditionalWeakTable InspectableInfoTable = new(); [ThreadStatic] internal static Type CreateRCWType; - - private static ComWrappers _comWrappers; - private static readonly object _comWrappersLock = new object(); - private static ComWrappers ComWrappers - { - get - { - if (_comWrappers is null) - { + + private static ComWrappers _comWrappers; + private static readonly object _comWrappersLock = new object(); + private static ComWrappers ComWrappers + { + get + { + if (_comWrappers is null) + { lock (_comWrappersLock) { if (_comWrappers is null) @@ -56,13 +56,13 @@ private static ComWrappers ComWrappers #if !EMBED ComWrappers.RegisterForTrackerSupport(comWrappersToSet); #endif - _comWrappers = comWrappersToSet; - } - } - } - return _comWrappers; - } - set + _comWrappers = comWrappersToSet; + } + } + } + return _comWrappers; + } + set { lock (_comWrappersLock) { @@ -74,37 +74,37 @@ private static ComWrappers ComWrappers #if !EMBED ComWrappers.RegisterForTrackerSupport(comWrappersToSet); #endif - _comWrappers = comWrappersToSet; - } - } - } - - internal static unsafe InspectableInfo GetInspectableInfo(IntPtr pThis) - { - var _this = FindObject(pThis); - return InspectableInfoTable.GetValue(_this.GetType(), o => PregenerateNativeTypeInformation(o).inspectableInfo); - } - + _comWrappers = comWrappersToSet; + } + } + } + + internal static unsafe InspectableInfo GetInspectableInfo(IntPtr pThis) + { + var _this = FindObject(pThis); + return InspectableInfoTable.GetValue(_this.GetType(), o => PregenerateNativeTypeInformation(o).inspectableInfo); + } + public static T CreateRcwForComObject(IntPtr ptr) { return CreateRcwForComObject(ptr, true); - } - - private static T CreateRcwForComObject(IntPtr ptr, bool tryUseCache) - { - if (ptr == IntPtr.Zero) - { - return default; - } - - // CreateRCWType is a thread local which is set here to communicate the statically known type - // when we are called by the ComWrappers API to create the object. We can't pass this through the - // ComWrappers API surface, so we are achieving it via a thread local. We unset it after in case - // there is other calls to it via other means. - CreateRCWType = typeof(T); - - var flags = tryUseCache ? CreateObjectFlags.TrackerObject : CreateObjectFlags.TrackerObject | CreateObjectFlags.UniqueInstance; - var rcw = ComWrappers.GetOrCreateObjectForComInstance(ptr, flags); + } + + private static T CreateRcwForComObject(IntPtr ptr, bool tryUseCache) + { + if (ptr == IntPtr.Zero) + { + return default; + } + + // CreateRCWType is a thread local which is set here to communicate the statically known type + // when we are called by the ComWrappers API to create the object. We can't pass this through the + // ComWrappers API surface, so we are achieving it via a thread local. We unset it after in case + // there is other calls to it via other means. + CreateRCWType = typeof(T); + + var flags = tryUseCache ? CreateObjectFlags.TrackerObject : CreateObjectFlags.TrackerObject | CreateObjectFlags.UniqueInstance; + var rcw = ComWrappers.GetOrCreateObjectForComInstance(ptr, flags); CreateRCWType = null; // Because .NET will de-duplicate strings and WinRT doesn't, // our RCW factory returns a wrapper of our string instance. @@ -121,7 +121,7 @@ private static T CreateRcwForComObject(IntPtr ptr, bool tryUseCache) _ when tryUseCache => CreateRcwForComObject(ptr, false), _ => throw new ArgumentException(string.Format("Unable to create a wrapper object. The WinRT object {0} has type {1} which cannot be assigned to type {2}", ptr, rcw.GetType(), typeof(T))) }; - + } public static bool TryUnwrapObject(object o, out IObjectReference objRef) @@ -145,38 +145,38 @@ public static bool TryUnwrapObject(object o, out IObjectReference objRef) return false; } - public static void RegisterObjectForInterface(object obj, IntPtr thisPtr, CreateObjectFlags createObjectFlags) => + public static void RegisterObjectForInterface(object obj, IntPtr thisPtr, CreateObjectFlags createObjectFlags) => ComWrappers.GetOrRegisterObjectForComInstance(thisPtr, createObjectFlags, obj); internal static void RegisterObjectForInterface(object obj, IntPtr thisPtr, IntPtr inner, CreateObjectFlags createObjectFlags) => ComWrappers.GetOrRegisterObjectForComInstance(thisPtr, createObjectFlags, obj, inner); - public static void RegisterObjectForInterface(object obj, IntPtr thisPtr) => - TryRegisterObjectForInterface(obj, thisPtr); - + public static void RegisterObjectForInterface(object obj, IntPtr thisPtr) => + TryRegisterObjectForInterface(obj, thisPtr); + public static object TryRegisterObjectForInterface(object obj, IntPtr thisPtr) { return ComWrappers.GetOrRegisterObjectForComInstance(thisPtr, CreateObjectFlags.TrackerObject, obj); - } - - internal static IntPtr CreateCCWForObjectUnsafe(object obj) - { - return ComWrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport); - } - - public static IObjectReference CreateCCWForObject(object obj) - { - IntPtr ccw = ComWrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport); - return ObjectReference.AttachFreeThreadedUnsafe(ref ccw); + } + + internal static IntPtr CreateCCWForObjectUnsafe(object obj) + { + return ComWrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport); + } + + public static IObjectReference CreateCCWForObject(object obj) + { + IntPtr ccw = ComWrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport); + return ObjectReference.AttachFreeThreadedUnsafe(ref ccw); } internal static IntPtr CreateCCWForObjectForABI(object obj, Guid iid) { - IntPtr ccw = ComWrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport); - - int hr = Marshal.QueryInterface(ccw, ref iid, out var iidCcw); - - Marshal.Release(ccw); + IntPtr ccw = ComWrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport); + + int hr = Marshal.QueryInterface(ccw, ref iid, out var iidCcw); + + Marshal.Release(ccw); if (hr < 0) { @@ -195,36 +195,36 @@ static void ThrowException(object obj, Guid iid, int hr) ThrowException(obj, iid, hr); } - return iidCcw; + return iidCcw; } - - public static unsafe T FindObject(IntPtr ptr) - where T : class => ComInterfaceDispatch.GetInstance((ComInterfaceDispatch*)ptr); - - public static IUnknownVftbl IUnknownVftbl => DefaultComWrappers.IUnknownVftbl; - public static IntPtr IUnknownVftblPtr => DefaultComWrappers.IUnknownVftblPtr; - - public static IntPtr AllocateVtableMemory(Type vtableType, int size) => RuntimeHelpers.AllocateTypeAssociatedMemory(vtableType, size); - - /// - /// Initialize the global instance to use for WinRT. - /// - /// The wrappers instance to use, or the default if null. - /// - /// A custom ComWrappers instance can be supplied to enable programs to fast-track some type resolution - /// instead of using reflection when the full type closure is known. - /// - public static void InitializeComWrappers(ComWrappers wrappers = null) - { - ComWrappers = wrappers; - } - - internal static Func GetTypedRcwFactory(Type implementationType) => TypedObjectFactoryCacheForType.GetOrAdd(implementationType, CreateTypedRcwFactory); - + + public static unsafe T FindObject(IntPtr ptr) + where T : class => ComInterfaceDispatch.GetInstance((ComInterfaceDispatch*)ptr); + + public static IUnknownVftbl IUnknownVftbl => DefaultComWrappers.IUnknownVftbl; + public static IntPtr IUnknownVftblPtr => DefaultComWrappers.IUnknownVftblPtr; + + public static IntPtr AllocateVtableMemory(Type vtableType, int size) => RuntimeHelpers.AllocateTypeAssociatedMemory(vtableType, size); + + /// + /// Initialize the global instance to use for WinRT. + /// + /// The wrappers instance to use, or the default if null. + /// + /// A custom ComWrappers instance can be supplied to enable programs to fast-track some type resolution + /// instead of using reflection when the full type closure is known. + /// + public static void InitializeComWrappers(ComWrappers wrappers = null) + { + ComWrappers = wrappers; + } + + internal static Func GetTypedRcwFactory(Type implementationType) => TypedObjectFactoryCacheForType.GetOrAdd(implementationType, CreateTypedRcwFactory); + public static bool RegisterTypedRcwFactory(Type implementationType, Func rcwFactory) => TypedObjectFactoryCacheForType.TryAdd(implementationType, rcwFactory); - private static Func CreateFactoryForImplementationType(string runtimeClassName, Type implementationType) - { + private static Func CreateFactoryForImplementationType(string runtimeClassName, Type implementationType) + { if (implementationType.IsGenericType) { if (!RuntimeFeature.IsDynamicCodeCompiled) @@ -240,11 +240,11 @@ private static Func CreateFactoryForImplementationType(str var createRcw = genericImplType.GetMethod("CreateRcw", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(IInspectable) }, null); return (Func)createRcw.CreateDelegate(typeof(Func)); } - } - - if (implementationType.IsInterface) - { - return obj => obj; + } + + if (implementationType.IsInterface) + { + return obj => obj; } // We never look for attributes on base types, since each [WinRTImplementationTypeRcwFactory] type acts as @@ -378,8 +378,8 @@ internal static string GetRuntimeClassNameForNonWinRTTypeFromLookupTable(Type ty internal #else public -#endif - class ComWrappersHelper +#endif + class ComWrappersHelper { public unsafe static void Init( bool isAggregation, @@ -399,35 +399,35 @@ public unsafe static void Init( IntPtr newInstance, IntPtr inner, Guid iidForNewInstance, - out IObjectReference objRef) + out IObjectReference objRef) { - objRef = ComWrappersSupport.GetObjectReferenceForInterface( - isAggregation ? inner : newInstance, - isAggregation ? IID.IID_IInspectable : iidForNewInstance, - requireQI: false); - + objRef = ComWrappersSupport.GetObjectReferenceForInterface( + isAggregation ? inner : newInstance, + isAggregation ? IID.IID_IInspectable : iidForNewInstance, + requireQI: false); + IntPtr referenceTracker; - { - // Determine if the instance supports IReferenceTracker (e.g. WinUI). - // Acquiring this interface is useful for: - // 1) Providing an indication of what value to pass during RCW creation. - // 2) Informing the Reference Tracker runtime during non-aggregation - // scenarios about new references. - // - // If aggregation, query the inner since that will have the implementation - // otherwise the new instance will be used. Since the inner was composed - // it should answer immediately without going through the outer. Either way - // the reference count will go to the new instance. - int hr = Marshal.QueryInterface(objRef.ThisPtr, ref Unsafe.AsRef(in IID.IID_IReferenceTracker), out referenceTracker); - if (hr != 0) - { - referenceTracker = default; - } - } - - { - // Determine flags needed for native object wrapper (i.e. RCW) creation. - var createObjectFlags = CreateObjectFlags.None; + { + // Determine if the instance supports IReferenceTracker (e.g. WinUI). + // Acquiring this interface is useful for: + // 1) Providing an indication of what value to pass during RCW creation. + // 2) Informing the Reference Tracker runtime during non-aggregation + // scenarios about new references. + // + // If aggregation, query the inner since that will have the implementation + // otherwise the new instance will be used. Since the inner was composed + // it should answer immediately without going through the outer. Either way + // the reference count will go to the new instance. + int hr = Marshal.QueryInterface(objRef.ThisPtr, ref Unsafe.AsRef(in IID.IID_IReferenceTracker), out referenceTracker); + if (hr != 0) + { + referenceTracker = default; + } + } + + { + // Determine flags needed for native object wrapper (i.e. RCW) creation. + var createObjectFlags = CreateObjectFlags.None; IntPtr instanceToWrap = newInstance; // The instance supports IReferenceTracker. @@ -442,32 +442,32 @@ public unsafe static void Init( // therefore it is important that the enclosing CCW forwards to its inner // if aggregation is involved. This is typically accomplished through an // implementation of ICustomQueryInterface. - if (isAggregation) - { - // Indicate the scenario is aggregation - createObjectFlags |= CreateObjectFlags.Aggregation; - - // The instance supports IReferenceTracker. - if (referenceTracker != default) - { - // IReferenceTracker is not needed in aggregation scenarios. - // It is not needed because all QueryInterface() calls on an - // object are followed by an immediately release of the returned - // pointer - see below for details. - Marshal.Release(referenceTracker); + if (isAggregation) + { + // Indicate the scenario is aggregation + createObjectFlags |= CreateObjectFlags.Aggregation; + + // The instance supports IReferenceTracker. + if (referenceTracker != default) + { + // IReferenceTracker is not needed in aggregation scenarios. + // It is not needed because all QueryInterface() calls on an + // object are followed by an immediately release of the returned + // pointer - see below for details. + Marshal.Release(referenceTracker); } - - ComWrappersSupport.RegisterObjectForInterface(thisInstance, instanceToWrap, inner, createObjectFlags); - } + + ComWrappersSupport.RegisterObjectForInterface(thisInstance, instanceToWrap, inner, createObjectFlags); + } else { ComWrappersSupport.RegisterObjectForInterface(thisInstance, instanceToWrap, createObjectFlags); - } - } - + } + } + // The following sets up the object reference to correctly handle AddRefs and releases - // based on the scenario. - if (isAggregation) + // based on the scenario. + if (isAggregation) { // Aggregation scenarios should avoid calling AddRef() on the // newInstance value. This is due to the semantics of COM Aggregation @@ -483,25 +483,25 @@ public unsafe static void Init( // IsAggregated and PreventReleaseOnDispose properties on IObjectReference. objRef.IsAggregated = true; // In WinUI scenario don't release inner - objRef.PreventReleaseOnDispose = referenceTracker != default; - } - else - { - if (referenceTracker != default) - { - // WinUI scenario - // This instance should be used to tell the - // Reference Tracker runtime whenever an AddRef()/Release() - // is performed on newInstance. + objRef.PreventReleaseOnDispose = referenceTracker != default; + } + else + { + if (referenceTracker != default) + { + // WinUI scenario + // This instance should be used to tell the + // Reference Tracker runtime whenever an AddRef()/Release() + // is performed on newInstance. objRef.ReferenceTrackerPtr = referenceTracker; // This instance is already AddRefFromTrackerSource by the CLR, // so it would also ReleaseFromTrackerSource on destruction. objRef.PreventReleaseFromTrackerSourceOnDispose = true; - Marshal.Release(referenceTracker); - } - + Marshal.Release(referenceTracker); + } + Marshal.Release(newInstance); } } @@ -509,9 +509,9 @@ public unsafe static void Init( public unsafe static void Init(IObjectReference objRef, bool addRefFromTrackerSource = true) { if (objRef.ReferenceTrackerPtr == IntPtr.Zero) - { - int hr = Marshal.QueryInterface(objRef.ThisPtr, ref Unsafe.AsRef(in IID.IID_IReferenceTracker), out var referenceTracker); - if (hr == 0) + { + int hr = Marshal.QueryInterface(objRef.ThisPtr, ref Unsafe.AsRef(in IID.IID_IReferenceTracker), out var referenceTracker); + if (hr == 0) { // WinUI scenario // This instance should be used to tell the @@ -528,38 +528,38 @@ public unsafe static void Init(IObjectReference objRef, bool addRefFromTrackerSo objRef.PreventReleaseFromTrackerSourceOnDispose = true; } - Marshal.Release(referenceTracker); + Marshal.Release(referenceTracker); } } - } - } - -#if EMBED - internal -#else - public -#endif - class DefaultComWrappers : ComWrappers - { - private static readonly ConditionalWeakTable TypeVtableEntryTable = new(); - public static unsafe IUnknownVftbl IUnknownVftbl => Unsafe.AsRef(IUnknownVftblPtr.ToPointer()); - - internal static IntPtr IUnknownVftblPtr { get; } - - static unsafe DefaultComWrappers() - { - GetIUnknownImpl(out var qi, out var addRef, out var release); - - IUnknownVftblPtr = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVftbl), sizeof(IUnknownVftbl)); - (*(IUnknownVftbl*)IUnknownVftblPtr) = new IUnknownVftbl - { - QueryInterface = (delegate* unmanaged[Stdcall])qi, - AddRef = (delegate* unmanaged[Stdcall])addRef, - Release = (delegate* unmanaged[Stdcall])release, - }; - } - - protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) + } + } + +#if EMBED + internal +#else + public +#endif + class DefaultComWrappers : ComWrappers + { + private static readonly ConditionalWeakTable TypeVtableEntryTable = new(); + public static unsafe IUnknownVftbl IUnknownVftbl => Unsafe.AsRef(IUnknownVftblPtr.ToPointer()); + + internal static IntPtr IUnknownVftblPtr { get; } + + static unsafe DefaultComWrappers() + { + GetIUnknownImpl(out var qi, out var addRef, out var release); + + IUnknownVftblPtr = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVftbl), sizeof(IUnknownVftbl)); + (*(IUnknownVftbl*)IUnknownVftblPtr) = new IUnknownVftbl + { + QueryInterface = (delegate* unmanaged[Stdcall])qi, + AddRef = (delegate* unmanaged[Stdcall])addRef, + Release = (delegate* unmanaged[Stdcall])release, + }; + } + + protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { var vtableEntries = TypeVtableEntryTable.GetValue(obj.GetType(), static (type) => { @@ -572,40 +572,40 @@ static unsafe DefaultComWrappers() return new VtableEntries(ComWrappersSupport.GetInterfaceTableEntries(type), type); }); - count = vtableEntries.Count; + count = vtableEntries.Count; if (count != 0 && !flags.HasFlag(CreateComInterfaceFlags.CallerDefinedIUnknown)) { // The vtable list unconditionally has the last entry as IUnknown, but it should // only be included if the flag is set. We achieve that by excluding the last entry // from the count if the flag isn't set. count -= 1; - } - - return vtableEntries.Data; - } - - private static unsafe bool IsRuntimeImplementedRCW(Type objType) - { - // Built-in COM interop isn't supported in AOT environments, - // so this method can only ever return false. Just inline it. + } + + return vtableEntries.Data; + } + + private static unsafe bool IsRuntimeImplementedRCW(Type objType) + { + // Built-in COM interop isn't supported in AOT environments, + // so this method can only ever return false. Just inline it. if (!RuntimeFeature.IsDynamicCodeCompiled) { return false; - } - - bool isRcw = objType.IsCOMObject; - if (objType.IsGenericType) - { - foreach (var arg in objType.GetGenericArguments()) - { - if (arg.IsCOMObject) - { - isRcw = true; - break; - } - } - } - return isRcw; + } + + bool isRcw = objType.IsCOMObject; + if (objType.IsGenericType) + { + foreach (var arg in objType.GetGenericArguments()) + { + if (arg.IsCOMObject) + { + isRcw = true; + break; + } + } + } + return isRcw; } private static object CreateObject(IntPtr externalComObject) @@ -651,24 +651,24 @@ private static object CreateObject(IntPtr externalComObject) ComWrappersHelper.Init(iunknownObjRef); return new SingleInterfaceOptimizedObject(typeof(IWeakReference), iunknownObjRef, false); - } + } else { // If the external COM object isn't IInspectable or IWeakReference, we can't handle it. // If we're registered globally, we want to let the runtime fall back for IUnknown and IDispatch support. // Return null so the runtime can fall back gracefully in IUnknown and IDispatch scenarios. return null; - } - } - finally + } + } + finally { MarshalExtensions.ReleaseIfNotNull(ptr); - } - } - - protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags) - { - var obj = CreateObject(externalComObject); + } + } + + protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags) + { + var obj = CreateObject(externalComObject); if (obj is IWinRTObject winrtObj && winrtObj.HasUnwrappableNativeObject && winrtObj.NativeObject != null) { // Handle the scenario where the CLR has already done an AddRefFromTrackerSource on the instance @@ -676,41 +676,41 @@ protected override object CreateObject(IntPtr externalComObject, CreateObjectFla // on destruction as the CLR would do it. winrtObj.NativeObject.ReleaseFromTrackerSource(); winrtObj.NativeObject.PreventReleaseFromTrackerSourceOnDispose = true; - } - - return obj; - } - - protected override void ReleaseObjects(IEnumerable objects) - { - foreach (var obj in objects) - { - if (ComWrappersSupport.TryUnwrapObject(obj, out var objRef)) - { - objRef.Dispose(); - } - } - } - - unsafe sealed class VtableEntries - { - public ComInterfaceEntry* Data { get; } - public int Count { get; } - + } + + return obj; + } + + protected override void ReleaseObjects(IEnumerable objects) + { + foreach (var obj in objects) + { + if (ComWrappersSupport.TryUnwrapObject(obj, out var objRef)) + { + objRef.Dispose(); + } + } + } + + unsafe sealed class VtableEntries + { + public ComInterfaceEntry* Data { get; } + public int Count { get; } + public VtableEntries() { Data = null; Count = 0; - } - - public VtableEntries(List entries, Type type) + } + + public VtableEntries(List entries, Type type) { Data = (ComInterfaceEntry*)RuntimeHelpers.AllocateTypeAssociatedMemory(type, sizeof(ComInterfaceEntry) * entries.Count); - CollectionsMarshal.AsSpan(entries).CopyTo(new Span(Data, entries.Count)); - - Count = entries.Count; - } - } - } -} + CollectionsMarshal.AsSpan(entries).CopyTo(new Span(Data, entries.Count)); + + Count = entries.Count; + } + } + } +} diff --git a/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs b/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs index 5bbb6c6a39..b88ce0adde 100644 --- a/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs +++ b/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs @@ -1,1280 +1,1280 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT; - -namespace Windows.Foundation -{ - internal enum PropertyType : uint - { - Empty = 0, - UInt8 = 0x1, - Int16 = 0x2, - UInt16 = 0x3, - Int32 = 0x4, - UInt32 = 0x5, - Int64 = 0x6, - UInt64 = 0x7, - Single = 0x8, - Double = 0x9, - Char16 = 0xa, - Boolean = 0xb, - String = 0xc, - Inspectable = 0xd, - DateTime = 0xe, - TimeSpan = 0xf, - Guid = 0x10, - Point = 0x11, - Size = 0x12, - Rect = 0x13, - OtherType = 0x14, - UInt8Array = 0x401, - Int16Array = 0x402, - UInt16Array = 0x403, - Int32Array = 0x404, - UInt32Array = 0x405, - Int64Array = 0x406, - UInt64Array = 0x407, - SingleArray = 0x408, - DoubleArray = 0x409, - Char16Array = 0x40a, - BooleanArray = 0x40b, - StringArray = 0x40c, - InspectableArray = 0x40d, - DateTimeArray = 0x40e, - TimeSpanArray = 0x40f, - GuidArray = 0x410, - PointArray = 0x411, - SizeArray = 0x412, - RectArray = 0x413, - OtherTypeArray = 0x414, - } -} - -namespace ABI.Windows.Foundation -{ - internal static class ManagedIPropertyValueImpl - { - private const int TYPE_E_TYPEMISMATCH = unchecked((int)0x80028CA0); - private const int DISP_E_OVERFLOW = unchecked((int)0x8002000A); - private static IPropertyValue.Vftbl AbiToProjectionVftable; - public static IntPtr AbiToProjectionVftablePtr; - - static unsafe ManagedIPropertyValueImpl() - { - AbiToProjectionVftable = new IPropertyValue.Vftbl - { - IInspectableVftbl = global::WinRT.IInspectable.Vftbl.AbiToProjectionVftable, - - _get_Type_0 = (delegate* unmanaged)&Do_Abi_get_Type_0, - _get_IsNumericScalar_1 = (delegate* unmanaged)&Do_Abi_get_IsNumericScalar_1, - _GetUInt8_2 = (delegate* unmanaged)&Do_Abi_GetUInt8_2, - _GetInt16_3 = (delegate* unmanaged)&Do_Abi_GetInt16_3, - _GetUInt16_4 = (delegate* unmanaged)&Do_Abi_GetUInt16_4, - _GetInt32_5 = (delegate* unmanaged)&Do_Abi_GetInt32_5, - _GetUInt32_6 = (delegate* unmanaged)&Do_Abi_GetUInt32_6, - _GetInt64_7 = (delegate* unmanaged)&Do_Abi_GetInt64_7, - _GetUInt64_8 = (delegate* unmanaged)&Do_Abi_GetUInt64_8, - _GetSingle_9 = (delegate* unmanaged)&Do_Abi_GetSingle_9, - _GetDouble_10 = (delegate* unmanaged)&Do_Abi_GetDouble_10, - _GetChar16_11 = (delegate* unmanaged)&Do_Abi_GetChar16_11, - _GetBoolean_12 = (delegate* unmanaged)&Do_Abi_GetBoolean_12, - _GetString_13 = (delegate* unmanaged)&Do_Abi_GetString_13, - _GetGuid_14 = (delegate* unmanaged)&Do_Abi_GetGuid_14, - _GetDateTime_15 = (delegate* unmanaged)&Do_Abi_GetDateTime_15, - _GetTimeSpan_16 = (delegate* unmanaged)&Do_Abi_GetTimeSpan_16, - _GetPoint_17 = (delegate* unmanaged)&Do_Abi_GetPoint_17, - _GetSize_18 = (delegate* unmanaged)&Do_Abi_GetSize_18, - _GetRect_19 = (delegate* unmanaged)&Do_Abi_GetRect_19, - _GetUInt8Array_20 = (delegate* unmanaged)&Do_Abi_GetUInt8Array_20, - _GetInt16Array_21 = (delegate* unmanaged)&Do_Abi_GetInt16Array_21, - _GetUInt16Array_22 = (delegate* unmanaged)&Do_Abi_GetUInt16Array_22, - _GetInt32Array_23 = (delegate* unmanaged)&Do_Abi_GetInt32Array_23, - _GetUInt32Array_24 = (delegate* unmanaged)&Do_Abi_GetUInt32Array_24, - _GetInt64Array_25 = (delegate* unmanaged)&Do_Abi_GetInt64Array_25, - _GetUInt64Array_26 = (delegate* unmanaged)&Do_Abi_GetUInt64Array_26, - _GetSingleArray_27 = (delegate* unmanaged)&Do_Abi_GetSingleArray_27, - _GetDoubleArray_28 = (delegate* unmanaged)&Do_Abi_GetDoubleArray_28, - _GetChar16Array_29 = (delegate* unmanaged)&Do_Abi_GetChar16Array_29, - _GetBooleanArray_30 = (delegate* unmanaged)&Do_Abi_GetBooleanArray_30, - _GetStringArray_31 = (delegate* unmanaged)&Do_Abi_GetStringArray_31, - _GetInspectableArray_32 = (delegate* unmanaged)&Do_Abi_GetInspectableArray_32, - _GetGuidArray_33 = (delegate* unmanaged)&Do_Abi_GetGuidArray_33, - _GetDateTimeArray_34 = (delegate* unmanaged)&Do_Abi_GetDateTimeArray_34, - _GetTimeSpanArray_35 = (delegate* unmanaged)&Do_Abi_GetTimeSpanArray_35, - _GetPointArray_36 = (delegate* unmanaged)&Do_Abi_GetPointArray_36, - _GetSizeArray_37 = (delegate* unmanaged)&Do_Abi_GetSizeArray_37, - _GetRectArray_38 = (delegate* unmanaged)&Do_Abi_GetRectArray_38, - - }; - var nativeVftbl = (IntPtr*)ComWrappersSupport.AllocateVtableMemory(typeof(ManagedIPropertyValueImpl), sizeof(global::WinRT.IInspectable.Vftbl) + sizeof(IntPtr) * 39); - *(IPropertyValue.Vftbl*)nativeVftbl = AbiToProjectionVftable; - AbiToProjectionVftablePtr = (IntPtr)nativeVftbl; - } - - private static volatile Dictionary s_numericScalarTypes; - - private static Dictionary NumericScalarTypes - { - get - { - if (s_numericScalarTypes == null) - { - var numericScalarTypes = new Dictionary { - { typeof(byte), global::Windows.Foundation.PropertyType.UInt8 }, - { typeof(short), global::Windows.Foundation.PropertyType.Int16 }, - { typeof(ushort), global::Windows.Foundation.PropertyType.UInt16 }, - { typeof(int), global::Windows.Foundation.PropertyType.Int32 }, - { typeof(uint), global::Windows.Foundation.PropertyType.UInt32 }, - { typeof(long), global::Windows.Foundation.PropertyType.Int64 }, - { typeof(ulong), global::Windows.Foundation.PropertyType.UInt64 }, - { typeof(float), global::Windows.Foundation.PropertyType.Single }, - { typeof(double), global::Windows.Foundation.PropertyType.Double } - }; - - s_numericScalarTypes = numericScalarTypes; - } - - return s_numericScalarTypes; - } - } - - /// - /// Unbox a value of a projected Windows.Foundation struct type. - /// - /// The target type. - /// The object to unbox. - /// The unboxed value. - private static T UnboxValue(object value) - where T : struct - { +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; + +namespace Windows.Foundation +{ + internal enum PropertyType : uint + { + Empty = 0, + UInt8 = 0x1, + Int16 = 0x2, + UInt16 = 0x3, + Int32 = 0x4, + UInt32 = 0x5, + Int64 = 0x6, + UInt64 = 0x7, + Single = 0x8, + Double = 0x9, + Char16 = 0xa, + Boolean = 0xb, + String = 0xc, + Inspectable = 0xd, + DateTime = 0xe, + TimeSpan = 0xf, + Guid = 0x10, + Point = 0x11, + Size = 0x12, + Rect = 0x13, + OtherType = 0x14, + UInt8Array = 0x401, + Int16Array = 0x402, + UInt16Array = 0x403, + Int32Array = 0x404, + UInt32Array = 0x405, + Int64Array = 0x406, + UInt64Array = 0x407, + SingleArray = 0x408, + DoubleArray = 0x409, + Char16Array = 0x40a, + BooleanArray = 0x40b, + StringArray = 0x40c, + InspectableArray = 0x40d, + DateTimeArray = 0x40e, + TimeSpanArray = 0x40f, + GuidArray = 0x410, + PointArray = 0x411, + SizeArray = 0x412, + RectArray = 0x413, + OtherTypeArray = 0x414, + } +} + +namespace ABI.Windows.Foundation +{ + internal static class ManagedIPropertyValueImpl + { + private const int TYPE_E_TYPEMISMATCH = unchecked((int)0x80028CA0); + private const int DISP_E_OVERFLOW = unchecked((int)0x8002000A); + private static IPropertyValue.Vftbl AbiToProjectionVftable; + public static IntPtr AbiToProjectionVftablePtr; + + static unsafe ManagedIPropertyValueImpl() + { + AbiToProjectionVftable = new IPropertyValue.Vftbl + { + IInspectableVftbl = global::WinRT.IInspectable.Vftbl.AbiToProjectionVftable, + + _get_Type_0 = (delegate* unmanaged)&Do_Abi_get_Type_0, + _get_IsNumericScalar_1 = (delegate* unmanaged)&Do_Abi_get_IsNumericScalar_1, + _GetUInt8_2 = (delegate* unmanaged)&Do_Abi_GetUInt8_2, + _GetInt16_3 = (delegate* unmanaged)&Do_Abi_GetInt16_3, + _GetUInt16_4 = (delegate* unmanaged)&Do_Abi_GetUInt16_4, + _GetInt32_5 = (delegate* unmanaged)&Do_Abi_GetInt32_5, + _GetUInt32_6 = (delegate* unmanaged)&Do_Abi_GetUInt32_6, + _GetInt64_7 = (delegate* unmanaged)&Do_Abi_GetInt64_7, + _GetUInt64_8 = (delegate* unmanaged)&Do_Abi_GetUInt64_8, + _GetSingle_9 = (delegate* unmanaged)&Do_Abi_GetSingle_9, + _GetDouble_10 = (delegate* unmanaged)&Do_Abi_GetDouble_10, + _GetChar16_11 = (delegate* unmanaged)&Do_Abi_GetChar16_11, + _GetBoolean_12 = (delegate* unmanaged)&Do_Abi_GetBoolean_12, + _GetString_13 = (delegate* unmanaged)&Do_Abi_GetString_13, + _GetGuid_14 = (delegate* unmanaged)&Do_Abi_GetGuid_14, + _GetDateTime_15 = (delegate* unmanaged)&Do_Abi_GetDateTime_15, + _GetTimeSpan_16 = (delegate* unmanaged)&Do_Abi_GetTimeSpan_16, + _GetPoint_17 = (delegate* unmanaged)&Do_Abi_GetPoint_17, + _GetSize_18 = (delegate* unmanaged)&Do_Abi_GetSize_18, + _GetRect_19 = (delegate* unmanaged)&Do_Abi_GetRect_19, + _GetUInt8Array_20 = (delegate* unmanaged)&Do_Abi_GetUInt8Array_20, + _GetInt16Array_21 = (delegate* unmanaged)&Do_Abi_GetInt16Array_21, + _GetUInt16Array_22 = (delegate* unmanaged)&Do_Abi_GetUInt16Array_22, + _GetInt32Array_23 = (delegate* unmanaged)&Do_Abi_GetInt32Array_23, + _GetUInt32Array_24 = (delegate* unmanaged)&Do_Abi_GetUInt32Array_24, + _GetInt64Array_25 = (delegate* unmanaged)&Do_Abi_GetInt64Array_25, + _GetUInt64Array_26 = (delegate* unmanaged)&Do_Abi_GetUInt64Array_26, + _GetSingleArray_27 = (delegate* unmanaged)&Do_Abi_GetSingleArray_27, + _GetDoubleArray_28 = (delegate* unmanaged)&Do_Abi_GetDoubleArray_28, + _GetChar16Array_29 = (delegate* unmanaged)&Do_Abi_GetChar16Array_29, + _GetBooleanArray_30 = (delegate* unmanaged)&Do_Abi_GetBooleanArray_30, + _GetStringArray_31 = (delegate* unmanaged)&Do_Abi_GetStringArray_31, + _GetInspectableArray_32 = (delegate* unmanaged)&Do_Abi_GetInspectableArray_32, + _GetGuidArray_33 = (delegate* unmanaged)&Do_Abi_GetGuidArray_33, + _GetDateTimeArray_34 = (delegate* unmanaged)&Do_Abi_GetDateTimeArray_34, + _GetTimeSpanArray_35 = (delegate* unmanaged)&Do_Abi_GetTimeSpanArray_35, + _GetPointArray_36 = (delegate* unmanaged)&Do_Abi_GetPointArray_36, + _GetSizeArray_37 = (delegate* unmanaged)&Do_Abi_GetSizeArray_37, + _GetRectArray_38 = (delegate* unmanaged)&Do_Abi_GetRectArray_38, + + }; + var nativeVftbl = (IntPtr*)ComWrappersSupport.AllocateVtableMemory(typeof(ManagedIPropertyValueImpl), sizeof(global::WinRT.IInspectable.Vftbl) + sizeof(IntPtr) * 39); + *(IPropertyValue.Vftbl*)nativeVftbl = AbiToProjectionVftable; + AbiToProjectionVftablePtr = (IntPtr)nativeVftbl; + } + + private static volatile Dictionary s_numericScalarTypes; + + private static Dictionary NumericScalarTypes + { + get + { + if (s_numericScalarTypes == null) + { + var numericScalarTypes = new Dictionary { + { typeof(byte), global::Windows.Foundation.PropertyType.UInt8 }, + { typeof(short), global::Windows.Foundation.PropertyType.Int16 }, + { typeof(ushort), global::Windows.Foundation.PropertyType.UInt16 }, + { typeof(int), global::Windows.Foundation.PropertyType.Int32 }, + { typeof(uint), global::Windows.Foundation.PropertyType.UInt32 }, + { typeof(long), global::Windows.Foundation.PropertyType.Int64 }, + { typeof(ulong), global::Windows.Foundation.PropertyType.UInt64 }, + { typeof(float), global::Windows.Foundation.PropertyType.Single }, + { typeof(double), global::Windows.Foundation.PropertyType.Double } + }; + + s_numericScalarTypes = numericScalarTypes; + } + + return s_numericScalarTypes; + } + } + + /// + /// Unbox a value of a projected Windows.Foundation struct type. + /// + /// The target type. + /// The object to unbox. + /// The unboxed value. + private static T UnboxValue(object value) + where T : struct + { if (value.GetType() == typeof(T)) { return (T)value; - } - - throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); - } - - private static T[] UnboxArray(object value) - where T : struct - { - if (!(value is Array dataArray)) - { - throw new InvalidCastException(); - } - - // If we do not have the correct array type, then we need to convert the array element-by-element - // to a new array of the requested type - T[] coercedArray = new T[dataArray.Length]; - for (int i = 0; i < dataArray.Length; ++i) - { - try - { - coercedArray[i] = UnboxValue(dataArray.GetValue(i)); - } - catch (InvalidCastException elementCastException) - { - //global::System.Exception e = new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueArrayCoersion, value.GetType(), typeof(T[]).Name, i, elementCastException.Message), elementCastException.HResult); - global::System.Exception e = new InvalidCastException("", elementCastException.HResult); - throw e; - } - } - return coercedArray; - } - - private static bool IsCoercable(object value) - { - // String <--> Guid is allowed - // Converting from an object to a string, Guid, or numeric scalar is allowed. - if (value.GetType() == typeof(string) || value.GetType() == typeof(Guid) || value.GetType() != typeof(object)) - { - return true; - } - - // All numeric scalars can also be coerced - return NumericScalarTypes.TryGetValue(value.GetType(), out _); - } - - /// - /// Coerce the managd object to an object of type . - /// - /// The target type. - /// The value. - /// The coerced value. - private static T CoerceValue(object value) - { - if (value is T u) - { - return u; - } - - if (!IsCoercable(value)) - { - throw new InvalidCastException(); - } - - try - { - if (value is string str && typeof(T) == typeof(Guid)) - { - return (T)(object)Guid.Parse(str); - } - else if (value is Guid guid && typeof(T) == typeof(string)) - { - return (T)(object)guid.ToString("D", global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(byte)) - { - return (T)(object)Convert.ToByte(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(short)) - { - return (T)(object)Convert.ToInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(ushort)) - { - return (T)(object)Convert.ToUInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(int)) - { - return (T)(object)Convert.ToInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(uint)) - { - return (T)(object)Convert.ToUInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(long)) - { - return (T)(object)Convert.ToInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(ulong)) - { - return (T)(object)Convert.ToUInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(float)) - { - return (T)(object)Convert.ToSingle(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else if (typeof(T) == typeof(double)) - { - return (T)(object)Convert.ToDouble(value, global::System.Globalization.CultureInfo.InvariantCulture); - } - else - { - Debug.Assert(!NumericScalarTypes.ContainsKey(typeof(T))); - throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); - } - } - catch (FormatException) - { - // throw new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueElement, value.GetType(), typeof(T).Name), TYPE_E_TYPEMISMATCH); - throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); - } - catch (InvalidCastException) - { - // throw new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueElement, value.GetType(), typeof(T).Name), TYPE_E_TYPEMISMATCH); - throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); - } - catch (OverflowException) - { - // throw new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueCoersion, value.GetType(), value, typeof(T).Name), DISP_E_OVERFLOW); - throw new InvalidCastException("", DISP_E_OVERFLOW); - } - - throw new InvalidCastException(); - } - - private static T[] CoerceArray(object value) - { - if (value is T[] arr) - { - return arr; - } - - if (!(value is Array dataArray)) - { - throw new InvalidCastException(); - } - - // If we do not have the correct array type, then we need to convert the array element-by-element - // to a new array of the requested type - T[] coercedArray = new T[dataArray.Length]; - for (int i = 0; i < dataArray.Length; ++i) - { - try - { - coercedArray[i] = CoerceValue(dataArray.GetValue(i)); - } - catch (InvalidCastException elementCastException) - { - //global::System.Exception e = new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueArrayCoersion, value.GetType(), typeof(T[]).Name, i, elementCastException.Message), elementCastException.HResult); - global::System.Exception e = new InvalidCastException("", elementCastException.HResult); - throw e; - } - } - return coercedArray; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt8_2(IntPtr thisPtr, byte* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetInt16_3(IntPtr thisPtr, short* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt16_4(IntPtr thisPtr, ushort* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetInt32_5(IntPtr thisPtr, int* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt32_6(IntPtr thisPtr, uint* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetInt64_7(IntPtr thisPtr, long* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt64_8(IntPtr thisPtr, ulong* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetSingle_9(IntPtr thisPtr, float* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetDouble_10(IntPtr thisPtr, double* value) - { - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetChar16_11(IntPtr thisPtr, ushort* value) - { - - try - { - *value = (ushort)CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetBoolean_12(IntPtr thisPtr, byte* value) - { - - try - { - *value = (byte)(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)) ? 1 : 0); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetString_13(IntPtr thisPtr, IntPtr* value) - { - - try - { - *value = MarshalString.FromManaged(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr))); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetGuid_14(IntPtr thisPtr, Guid* value) - { - - try - { - *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetDateTime_15(IntPtr thisPtr, global::ABI.System.DateTimeOffset* value) - { - - try - { - *value = ABI.System.DateTimeOffset.FromManaged(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr))); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetTimeSpan_16(IntPtr thisPtr, global::ABI.System.TimeSpan* value) - { - - try - { - *value = ABI.System.TimeSpan.FromManaged(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr))); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetPoint_17(IntPtr thisPtr, global::Windows.Foundation.Point* value) - { - - try - { - *value = UnboxValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetSize_18(IntPtr thisPtr, global::Windows.Foundation.Size* value) - { - - try - { - *value = UnboxValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetRect_19(IntPtr thisPtr, global::Windows.Foundation.Rect* value) - { - - try - { - *value = UnboxValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt8Array_20(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - byte[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetInt16Array_21(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - short[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt16Array_22(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - ushort[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetInt32Array_23(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - int[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt32Array_24(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - uint[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetInt64Array_25(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - long[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetUInt64Array_26(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - ulong[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetSingleArray_27(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - float[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetDoubleArray_28(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - double[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetChar16Array_29(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - char[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetBooleanArray_30(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - bool[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetStringArray_31(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - string[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalString.FromManagedArray(__value); - - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetInspectableArray_32(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - object[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalInspectable.FromManagedArray(__value); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetGuidArray_33(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - Guid[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetDateTimeArray_34(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - global::System.DateTimeOffset[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); - - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetTimeSpanArray_35(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - global::System.TimeSpan[] __value = default; - - try - { - __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); - - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetPointArray_36(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - global::Windows.Foundation.Point[] __value = default; - - try - { - __value = UnboxArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetSizeArray_37(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - global::Windows.Foundation.Size[] __value = default; - - try - { - __value = UnboxArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_GetRectArray_38(IntPtr thisPtr, int* __valueSize, IntPtr* value) - { - - - - global::Windows.Foundation.Rect[] __value = default; - - try - { - __value = UnboxArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); - - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_get_IsNumericScalar_1(IntPtr thisPtr, byte* value) - { - - try - { - *value = (byte)(NumericScalarTypes.TryGetValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetType(), out _) ? 1 : 0); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - - [UnmanagedCallersOnly] - - private static unsafe int Do_Abi_get_Type_0(IntPtr thisPtr, global::Windows.Foundation.PropertyType* value) - { - - try - { - *value = GetPropertyTypeOfObject(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - private static unsafe global::Windows.Foundation.PropertyType GetPropertyTypeOfObject(object obj) - { - global::Windows.Foundation.PropertyType value; - global::System.Type managedType = obj.GetType(); - bool isArray = managedType.IsArray; - if (isArray) - { - managedType = managedType.GetElementType(); - } - if (!NumericScalarTypes.TryGetValue(managedType, out value)) - { - if (managedType == typeof(string)) - { - value = global::Windows.Foundation.PropertyType.String; - } - else if (managedType == typeof(char)) - { - value = global::Windows.Foundation.PropertyType.Char16; - } - else if (managedType == typeof(bool)) - { - value = global::Windows.Foundation.PropertyType.Boolean; - } - else if (managedType == typeof(global::System.DateTimeOffset)) - { - value = global::Windows.Foundation.PropertyType.DateTime; - } - else if (managedType == typeof(global::System.TimeSpan)) - { - value = global::Windows.Foundation.PropertyType.TimeSpan; - } - else if (managedType == typeof(global::System.Guid)) - { - value = global::Windows.Foundation.PropertyType.Guid; - } - else if (string.CompareOrdinal(managedType.FullName, "Windows.Foundation.Point") == 0) - { - value = global::Windows.Foundation.PropertyType.Point; - } - else if (string.CompareOrdinal(managedType.FullName, "Windows.Foundation.Rect") == 0) - { - value = global::Windows.Foundation.PropertyType.Rect; - } - else if (string.CompareOrdinal(managedType.FullName, "Windows.Foundation.Size") == 0) - { - value = global::Windows.Foundation.PropertyType.Size; - } - else if (managedType == typeof(object)) - { - value = global::Windows.Foundation.PropertyType.Inspectable; - } - else if (typeof(Delegate).IsAssignableFrom(managedType)) - { - value = global::Windows.Foundation.PropertyType.OtherType; - } - else if (!managedType.IsValueType && managedType != typeof(Type) && isArray) - { - // Treat arrays of interfaces as though they are arrays of object. - value = global::Windows.Foundation.PropertyType.Inspectable; - } - else - { - value = global::Windows.Foundation.PropertyType.OtherType; - } - } - if (isArray) - { - // The array values for Windows.Foundation.PropertyType are all 1024 above their scalar equivalents - value = (global::Windows.Foundation.PropertyType)((int)value + 1024); - } - - return value; - } - } - - [Guid("4BD682DD-7554-40E9-9A9B-82654EDE7E62")] - internal unsafe interface IPropertyValue - { - [Guid("4BD682DD-7554-40E9-9A9B-82654EDE7E62")] -#pragma warning disable CA2257 // This member is a type (so it cannot be invoked) - public struct Vftbl -#pragma warning restore CA2257 - { - internal IInspectable.Vftbl IInspectableVftbl; - internal void* _get_Type_0; - public delegate* unmanaged[Stdcall] get_Type_0 { get => (delegate* unmanaged[Stdcall])_get_Type_0; set => _get_Type_0 = value; } - public void* _get_IsNumericScalar_1; - public delegate* unmanaged[Stdcall] get_IsNumericScalar_1 { get => (delegate* unmanaged[Stdcall])_get_IsNumericScalar_1; set => _get_IsNumericScalar_1 = value; } - internal void* _GetUInt8_2; - public delegate* unmanaged[Stdcall] GetUInt8_2 { get => (delegate* unmanaged[Stdcall])_GetUInt8_2; set => _GetUInt8_2 = value; } - internal void* _GetInt16_3; - public delegate* unmanaged[Stdcall] GetInt16_3 { get => (delegate* unmanaged[Stdcall])_GetInt16_3; set => _GetInt16_3 = value; } - internal void* _GetUInt16_4; - public delegate* unmanaged[Stdcall] GetUInt16_4 { get => (delegate* unmanaged[Stdcall])_GetUInt16_4; set => _GetUInt16_4 = value; } - internal void* _GetInt32_5; - public delegate* unmanaged[Stdcall] GetInt32_5 { get => (delegate* unmanaged[Stdcall])_GetInt32_5; set => _GetInt32_5 = value; } - internal void* _GetUInt32_6; - public delegate* unmanaged[Stdcall] GetUInt32_6 { get => (delegate* unmanaged[Stdcall])_GetUInt32_6; set => _GetUInt32_6 = value; } - internal void* _GetInt64_7; - public delegate* unmanaged[Stdcall] GetInt64_7 { get => (delegate* unmanaged[Stdcall])_GetInt64_7; set => _GetInt64_7 = value; } - internal void* _GetUInt64_8; - public delegate* unmanaged[Stdcall] GetUInt64_8 { get => (delegate* unmanaged[Stdcall])_GetUInt64_8; set => _GetUInt64_8 = value; } - internal void* _GetSingle_9; - public delegate* unmanaged[Stdcall] GetSingle_9 { get => (delegate* unmanaged[Stdcall])_GetSingle_9; set => _GetSingle_9 = value; } - internal void* _GetDouble_10; - public delegate* unmanaged[Stdcall] GetDouble_10 { get => (delegate* unmanaged[Stdcall])_GetDouble_10; set => _GetDouble_10 = value; } - internal void* _GetChar16_11; - public delegate* unmanaged[Stdcall] GetChar16_11 { get => (delegate* unmanaged[Stdcall])_GetChar16_11; set => _GetChar16_11 = value; } - internal void* _GetBoolean_12; - public delegate* unmanaged[Stdcall] GetBoolean_12 { get => (delegate* unmanaged[Stdcall])_GetBoolean_12; set => _GetBoolean_12 = value; } - internal void* _GetString_13; - public delegate* unmanaged[Stdcall] GetString_13 { get => (delegate* unmanaged[Stdcall])_GetString_13; set => _GetString_13 = value; } - internal void* _GetGuid_14; - public delegate* unmanaged[Stdcall] GetGuid_14 { get => (delegate* unmanaged[Stdcall])_GetGuid_14; set => _GetGuid_14 = value; } - internal void* _GetDateTime_15; - public delegate* unmanaged[Stdcall] GetDateTime_15 { get => (delegate* unmanaged[Stdcall])_GetDateTime_15; set => _GetDateTime_15 = value; } - internal void* _GetTimeSpan_16; - public delegate* unmanaged[Stdcall] GetTimeSpan_16 { get => (delegate* unmanaged[Stdcall])_GetTimeSpan_16; set => _GetTimeSpan_16 = value; } - internal void* _GetPoint_17; - public delegate* unmanaged[Stdcall] GetPoint_17 { get => (delegate* unmanaged[Stdcall])_GetPoint_17; set => _GetPoint_17 = value; } - internal void* _GetSize_18; - public delegate* unmanaged[Stdcall] GetSize_18 { get => (delegate* unmanaged[Stdcall])_GetSize_18; set => _GetSize_18 = value; } - internal void* _GetRect_19; - public delegate* unmanaged[Stdcall] GetRect_19 { get => (delegate* unmanaged[Stdcall])_GetRect_19; set => _GetRect_19 = value; } - internal void* _GetUInt8Array_20; - public delegate* unmanaged[Stdcall] GetUInt8Array_20 { get => (delegate* unmanaged[Stdcall])_GetUInt8Array_20; set => _GetUInt8Array_20 = value; } - internal void* _GetInt16Array_21; - public delegate* unmanaged[Stdcall] GetInt16Array_21 { get => (delegate* unmanaged[Stdcall])_GetInt16Array_21; set => _GetInt16Array_21 = value; } - internal void* _GetUInt16Array_22; - public delegate* unmanaged[Stdcall] GetUInt16Array_22 { get => (delegate* unmanaged[Stdcall])_GetUInt16Array_22; set => _GetUInt16Array_22 = value; } - internal void* _GetInt32Array_23; - public delegate* unmanaged[Stdcall] GetInt32Array_23 { get => (delegate* unmanaged[Stdcall])_GetInt32Array_23; set => _GetInt32Array_23 = value; } - internal void* _GetUInt32Array_24; - public delegate* unmanaged[Stdcall] GetUInt32Array_24 { get => (delegate* unmanaged[Stdcall])_GetUInt32Array_24; set => _GetUInt32Array_24 = value; } - internal void* _GetInt64Array_25; - public delegate* unmanaged[Stdcall] GetInt64Array_25 { get => (delegate* unmanaged[Stdcall])_GetInt64Array_25; set => _GetInt64Array_25 = value; } - internal void* _GetUInt64Array_26; - public delegate* unmanaged[Stdcall] GetUInt64Array_26 { get => (delegate* unmanaged[Stdcall])_GetUInt64Array_26; set => _GetUInt64Array_26 = value; } - internal void* _GetSingleArray_27; - public delegate* unmanaged[Stdcall] GetSingleArray_27 { get => (delegate* unmanaged[Stdcall])_GetSingleArray_27; set => _GetSingleArray_27 = value; } - internal void* _GetDoubleArray_28; - public delegate* unmanaged[Stdcall] GetDoubleArray_28 { get => (delegate* unmanaged[Stdcall])_GetDoubleArray_28; set => _GetDoubleArray_28 = value; } - internal void* _GetChar16Array_29; - public delegate* unmanaged[Stdcall] GetChar16Array_29 { get => (delegate* unmanaged[Stdcall])_GetChar16Array_29; set => _GetChar16Array_29 = value; } - internal void* _GetBooleanArray_30; - public delegate* unmanaged[Stdcall] GetBooleanArray_30 { get => (delegate* unmanaged[Stdcall])_GetBooleanArray_30; set => _GetBooleanArray_30 = value; } - internal void* _GetStringArray_31; - public delegate* unmanaged[Stdcall] GetStringArray_31 { get => (delegate* unmanaged[Stdcall])_GetStringArray_31; set => _GetStringArray_31 = value; } - internal void* _GetInspectableArray_32; - public delegate* unmanaged[Stdcall] GetInspectableArray_32 { get => (delegate* unmanaged[Stdcall])_GetInspectableArray_32; set => _GetInspectableArray_32 = value; } - internal void* _GetGuidArray_33; - public delegate* unmanaged[Stdcall] GetGuidArray_33 { get => (delegate* unmanaged[Stdcall])_GetGuidArray_33; set => _GetGuidArray_33 = value; } - internal void* _GetDateTimeArray_34; - public delegate* unmanaged[Stdcall] GetDateTimeArray_34 { get => (delegate* unmanaged[Stdcall])_GetDateTimeArray_34; set => _GetDateTimeArray_34 = value; } - internal void* _GetTimeSpanArray_35; - public delegate* unmanaged[Stdcall] GetTimeSpanArray_35 { get => (delegate* unmanaged[Stdcall])_GetTimeSpanArray_35; set => _GetTimeSpanArray_35 = value; } - internal void* _GetPointArray_36; - public delegate* unmanaged[Stdcall] GetPointArray_36 { get => (delegate* unmanaged[Stdcall])_GetPointArray_36; set => _GetPointArray_36 = value; } - internal void* _GetSizeArray_37; - public delegate* unmanaged[Stdcall] GetSizeArray_37 { get => (delegate* unmanaged[Stdcall])_GetSizeArray_37; set => _GetSizeArray_37 = value; } - internal void* _GetRectArray_38; - public delegate* unmanaged[Stdcall] GetRectArray_38 { get => (delegate* unmanaged[Stdcall])_GetRectArray_38; set => _GetRectArray_38 = value; } - } - } -} + } + + throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); + } + + private static T[] UnboxArray(object value) + where T : struct + { + if (!(value is Array dataArray)) + { + throw new InvalidCastException(); + } + + // If we do not have the correct array type, then we need to convert the array element-by-element + // to a new array of the requested type + T[] coercedArray = new T[dataArray.Length]; + for (int i = 0; i < dataArray.Length; ++i) + { + try + { + coercedArray[i] = UnboxValue(dataArray.GetValue(i)); + } + catch (InvalidCastException elementCastException) + { + //global::System.Exception e = new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueArrayCoersion, value.GetType(), typeof(T[]).Name, i, elementCastException.Message), elementCastException.HResult); + global::System.Exception e = new InvalidCastException("", elementCastException.HResult); + throw e; + } + } + return coercedArray; + } + + private static bool IsCoercable(object value) + { + // String <--> Guid is allowed + // Converting from an object to a string, Guid, or numeric scalar is allowed. + if (value.GetType() == typeof(string) || value.GetType() == typeof(Guid) || value.GetType() != typeof(object)) + { + return true; + } + + // All numeric scalars can also be coerced + return NumericScalarTypes.TryGetValue(value.GetType(), out _); + } + + /// + /// Coerce the managd object to an object of type . + /// + /// The target type. + /// The value. + /// The coerced value. + private static T CoerceValue(object value) + { + if (value is T u) + { + return u; + } + + if (!IsCoercable(value)) + { + throw new InvalidCastException(); + } + + try + { + if (value is string str && typeof(T) == typeof(Guid)) + { + return (T)(object)Guid.Parse(str); + } + else if (value is Guid guid && typeof(T) == typeof(string)) + { + return (T)(object)guid.ToString("D", global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(byte)) + { + return (T)(object)Convert.ToByte(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(short)) + { + return (T)(object)Convert.ToInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(ushort)) + { + return (T)(object)Convert.ToUInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(int)) + { + return (T)(object)Convert.ToInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(uint)) + { + return (T)(object)Convert.ToUInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(long)) + { + return (T)(object)Convert.ToInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(ulong)) + { + return (T)(object)Convert.ToUInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(float)) + { + return (T)(object)Convert.ToSingle(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(double)) + { + return (T)(object)Convert.ToDouble(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else + { + Debug.Assert(!NumericScalarTypes.ContainsKey(typeof(T))); + throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); + } + } + catch (FormatException) + { + // throw new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueElement, value.GetType(), typeof(T).Name), TYPE_E_TYPEMISMATCH); + throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); + } + catch (InvalidCastException) + { + // throw new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueElement, value.GetType(), typeof(T).Name), TYPE_E_TYPEMISMATCH); + throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); + } + catch (OverflowException) + { + // throw new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueCoersion, value.GetType(), value, typeof(T).Name), DISP_E_OVERFLOW); + throw new InvalidCastException("", DISP_E_OVERFLOW); + } + + throw new InvalidCastException(); + } + + private static T[] CoerceArray(object value) + { + if (value is T[] arr) + { + return arr; + } + + if (!(value is Array dataArray)) + { + throw new InvalidCastException(); + } + + // If we do not have the correct array type, then we need to convert the array element-by-element + // to a new array of the requested type + T[] coercedArray = new T[dataArray.Length]; + for (int i = 0; i < dataArray.Length; ++i) + { + try + { + coercedArray[i] = CoerceValue(dataArray.GetValue(i)); + } + catch (InvalidCastException elementCastException) + { + //global::System.Exception e = new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueArrayCoersion, value.GetType(), typeof(T[]).Name, i, elementCastException.Message), elementCastException.HResult); + global::System.Exception e = new InvalidCastException("", elementCastException.HResult); + throw e; + } + } + return coercedArray; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt8_2(IntPtr thisPtr, byte* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetInt16_3(IntPtr thisPtr, short* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt16_4(IntPtr thisPtr, ushort* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetInt32_5(IntPtr thisPtr, int* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt32_6(IntPtr thisPtr, uint* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetInt64_7(IntPtr thisPtr, long* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt64_8(IntPtr thisPtr, ulong* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetSingle_9(IntPtr thisPtr, float* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetDouble_10(IntPtr thisPtr, double* value) + { + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetChar16_11(IntPtr thisPtr, ushort* value) + { + + try + { + *value = (ushort)CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetBoolean_12(IntPtr thisPtr, byte* value) + { + + try + { + *value = (byte)(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)) ? 1 : 0); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetString_13(IntPtr thisPtr, IntPtr* value) + { + + try + { + *value = MarshalString.FromManaged(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr))); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetGuid_14(IntPtr thisPtr, Guid* value) + { + + try + { + *value = CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetDateTime_15(IntPtr thisPtr, global::ABI.System.DateTimeOffset* value) + { + + try + { + *value = ABI.System.DateTimeOffset.FromManaged(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr))); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetTimeSpan_16(IntPtr thisPtr, global::ABI.System.TimeSpan* value) + { + + try + { + *value = ABI.System.TimeSpan.FromManaged(CoerceValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr))); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetPoint_17(IntPtr thisPtr, global::Windows.Foundation.Point* value) + { + + try + { + *value = UnboxValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetSize_18(IntPtr thisPtr, global::Windows.Foundation.Size* value) + { + + try + { + *value = UnboxValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetRect_19(IntPtr thisPtr, global::Windows.Foundation.Rect* value) + { + + try + { + *value = UnboxValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt8Array_20(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + byte[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetInt16Array_21(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + short[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt16Array_22(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + ushort[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetInt32Array_23(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + int[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt32Array_24(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + uint[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetInt64Array_25(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + long[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetUInt64Array_26(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + ulong[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetSingleArray_27(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + float[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetDoubleArray_28(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + double[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetChar16Array_29(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + char[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetBooleanArray_30(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + bool[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetStringArray_31(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + string[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalString.FromManagedArray(__value); + + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetInspectableArray_32(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + object[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalInspectable.FromManagedArray(__value); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetGuidArray_33(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + Guid[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetDateTimeArray_34(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + global::System.DateTimeOffset[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); + + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetTimeSpanArray_35(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + global::System.TimeSpan[] __value = default; + + try + { + __value = CoerceArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalNonBlittable.FromManagedArray(__value); + + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetPointArray_36(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + global::Windows.Foundation.Point[] __value = default; + + try + { + __value = UnboxArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetSizeArray_37(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + global::Windows.Foundation.Size[] __value = default; + + try + { + __value = UnboxArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_GetRectArray_38(IntPtr thisPtr, int* __valueSize, IntPtr* value) + { + + + + global::Windows.Foundation.Rect[] __value = default; + + try + { + __value = UnboxArray(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + (*__valueSize, *value) = MarshalBlittable.FromManagedArray(__value); + + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_get_IsNumericScalar_1(IntPtr thisPtr, byte* value) + { + + try + { + *value = (byte)(NumericScalarTypes.TryGetValue(global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetType(), out _) ? 1 : 0); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + + [UnmanagedCallersOnly] + + private static unsafe int Do_Abi_get_Type_0(IntPtr thisPtr, global::Windows.Foundation.PropertyType* value) + { + + try + { + *value = GetPropertyTypeOfObject(global::WinRT.ComWrappersSupport.FindObject(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + private static unsafe global::Windows.Foundation.PropertyType GetPropertyTypeOfObject(object obj) + { + global::Windows.Foundation.PropertyType value; + global::System.Type managedType = obj.GetType(); + bool isArray = managedType.IsArray; + if (isArray) + { + managedType = managedType.GetElementType(); + } + if (!NumericScalarTypes.TryGetValue(managedType, out value)) + { + if (managedType == typeof(string)) + { + value = global::Windows.Foundation.PropertyType.String; + } + else if (managedType == typeof(char)) + { + value = global::Windows.Foundation.PropertyType.Char16; + } + else if (managedType == typeof(bool)) + { + value = global::Windows.Foundation.PropertyType.Boolean; + } + else if (managedType == typeof(global::System.DateTimeOffset)) + { + value = global::Windows.Foundation.PropertyType.DateTime; + } + else if (managedType == typeof(global::System.TimeSpan)) + { + value = global::Windows.Foundation.PropertyType.TimeSpan; + } + else if (managedType == typeof(global::System.Guid)) + { + value = global::Windows.Foundation.PropertyType.Guid; + } + else if (string.CompareOrdinal(managedType.FullName, "Windows.Foundation.Point") == 0) + { + value = global::Windows.Foundation.PropertyType.Point; + } + else if (string.CompareOrdinal(managedType.FullName, "Windows.Foundation.Rect") == 0) + { + value = global::Windows.Foundation.PropertyType.Rect; + } + else if (string.CompareOrdinal(managedType.FullName, "Windows.Foundation.Size") == 0) + { + value = global::Windows.Foundation.PropertyType.Size; + } + else if (managedType == typeof(object)) + { + value = global::Windows.Foundation.PropertyType.Inspectable; + } + else if (typeof(Delegate).IsAssignableFrom(managedType)) + { + value = global::Windows.Foundation.PropertyType.OtherType; + } + else if (!managedType.IsValueType && managedType != typeof(Type) && isArray) + { + // Treat arrays of interfaces as though they are arrays of object. + value = global::Windows.Foundation.PropertyType.Inspectable; + } + else + { + value = global::Windows.Foundation.PropertyType.OtherType; + } + } + if (isArray) + { + // The array values for Windows.Foundation.PropertyType are all 1024 above their scalar equivalents + value = (global::Windows.Foundation.PropertyType)((int)value + 1024); + } + + return value; + } + } + + [Guid("4BD682DD-7554-40E9-9A9B-82654EDE7E62")] + internal unsafe interface IPropertyValue + { + [Guid("4BD682DD-7554-40E9-9A9B-82654EDE7E62")] +#pragma warning disable CA2257 // This member is a type (so it cannot be invoked) + public struct Vftbl +#pragma warning restore CA2257 + { + internal IInspectable.Vftbl IInspectableVftbl; + internal void* _get_Type_0; + public delegate* unmanaged[Stdcall] get_Type_0 { get => (delegate* unmanaged[Stdcall])_get_Type_0; set => _get_Type_0 = value; } + public void* _get_IsNumericScalar_1; + public delegate* unmanaged[Stdcall] get_IsNumericScalar_1 { get => (delegate* unmanaged[Stdcall])_get_IsNumericScalar_1; set => _get_IsNumericScalar_1 = value; } + internal void* _GetUInt8_2; + public delegate* unmanaged[Stdcall] GetUInt8_2 { get => (delegate* unmanaged[Stdcall])_GetUInt8_2; set => _GetUInt8_2 = value; } + internal void* _GetInt16_3; + public delegate* unmanaged[Stdcall] GetInt16_3 { get => (delegate* unmanaged[Stdcall])_GetInt16_3; set => _GetInt16_3 = value; } + internal void* _GetUInt16_4; + public delegate* unmanaged[Stdcall] GetUInt16_4 { get => (delegate* unmanaged[Stdcall])_GetUInt16_4; set => _GetUInt16_4 = value; } + internal void* _GetInt32_5; + public delegate* unmanaged[Stdcall] GetInt32_5 { get => (delegate* unmanaged[Stdcall])_GetInt32_5; set => _GetInt32_5 = value; } + internal void* _GetUInt32_6; + public delegate* unmanaged[Stdcall] GetUInt32_6 { get => (delegate* unmanaged[Stdcall])_GetUInt32_6; set => _GetUInt32_6 = value; } + internal void* _GetInt64_7; + public delegate* unmanaged[Stdcall] GetInt64_7 { get => (delegate* unmanaged[Stdcall])_GetInt64_7; set => _GetInt64_7 = value; } + internal void* _GetUInt64_8; + public delegate* unmanaged[Stdcall] GetUInt64_8 { get => (delegate* unmanaged[Stdcall])_GetUInt64_8; set => _GetUInt64_8 = value; } + internal void* _GetSingle_9; + public delegate* unmanaged[Stdcall] GetSingle_9 { get => (delegate* unmanaged[Stdcall])_GetSingle_9; set => _GetSingle_9 = value; } + internal void* _GetDouble_10; + public delegate* unmanaged[Stdcall] GetDouble_10 { get => (delegate* unmanaged[Stdcall])_GetDouble_10; set => _GetDouble_10 = value; } + internal void* _GetChar16_11; + public delegate* unmanaged[Stdcall] GetChar16_11 { get => (delegate* unmanaged[Stdcall])_GetChar16_11; set => _GetChar16_11 = value; } + internal void* _GetBoolean_12; + public delegate* unmanaged[Stdcall] GetBoolean_12 { get => (delegate* unmanaged[Stdcall])_GetBoolean_12; set => _GetBoolean_12 = value; } + internal void* _GetString_13; + public delegate* unmanaged[Stdcall] GetString_13 { get => (delegate* unmanaged[Stdcall])_GetString_13; set => _GetString_13 = value; } + internal void* _GetGuid_14; + public delegate* unmanaged[Stdcall] GetGuid_14 { get => (delegate* unmanaged[Stdcall])_GetGuid_14; set => _GetGuid_14 = value; } + internal void* _GetDateTime_15; + public delegate* unmanaged[Stdcall] GetDateTime_15 { get => (delegate* unmanaged[Stdcall])_GetDateTime_15; set => _GetDateTime_15 = value; } + internal void* _GetTimeSpan_16; + public delegate* unmanaged[Stdcall] GetTimeSpan_16 { get => (delegate* unmanaged[Stdcall])_GetTimeSpan_16; set => _GetTimeSpan_16 = value; } + internal void* _GetPoint_17; + public delegate* unmanaged[Stdcall] GetPoint_17 { get => (delegate* unmanaged[Stdcall])_GetPoint_17; set => _GetPoint_17 = value; } + internal void* _GetSize_18; + public delegate* unmanaged[Stdcall] GetSize_18 { get => (delegate* unmanaged[Stdcall])_GetSize_18; set => _GetSize_18 = value; } + internal void* _GetRect_19; + public delegate* unmanaged[Stdcall] GetRect_19 { get => (delegate* unmanaged[Stdcall])_GetRect_19; set => _GetRect_19 = value; } + internal void* _GetUInt8Array_20; + public delegate* unmanaged[Stdcall] GetUInt8Array_20 { get => (delegate* unmanaged[Stdcall])_GetUInt8Array_20; set => _GetUInt8Array_20 = value; } + internal void* _GetInt16Array_21; + public delegate* unmanaged[Stdcall] GetInt16Array_21 { get => (delegate* unmanaged[Stdcall])_GetInt16Array_21; set => _GetInt16Array_21 = value; } + internal void* _GetUInt16Array_22; + public delegate* unmanaged[Stdcall] GetUInt16Array_22 { get => (delegate* unmanaged[Stdcall])_GetUInt16Array_22; set => _GetUInt16Array_22 = value; } + internal void* _GetInt32Array_23; + public delegate* unmanaged[Stdcall] GetInt32Array_23 { get => (delegate* unmanaged[Stdcall])_GetInt32Array_23; set => _GetInt32Array_23 = value; } + internal void* _GetUInt32Array_24; + public delegate* unmanaged[Stdcall] GetUInt32Array_24 { get => (delegate* unmanaged[Stdcall])_GetUInt32Array_24; set => _GetUInt32Array_24 = value; } + internal void* _GetInt64Array_25; + public delegate* unmanaged[Stdcall] GetInt64Array_25 { get => (delegate* unmanaged[Stdcall])_GetInt64Array_25; set => _GetInt64Array_25 = value; } + internal void* _GetUInt64Array_26; + public delegate* unmanaged[Stdcall] GetUInt64Array_26 { get => (delegate* unmanaged[Stdcall])_GetUInt64Array_26; set => _GetUInt64Array_26 = value; } + internal void* _GetSingleArray_27; + public delegate* unmanaged[Stdcall] GetSingleArray_27 { get => (delegate* unmanaged[Stdcall])_GetSingleArray_27; set => _GetSingleArray_27 = value; } + internal void* _GetDoubleArray_28; + public delegate* unmanaged[Stdcall] GetDoubleArray_28 { get => (delegate* unmanaged[Stdcall])_GetDoubleArray_28; set => _GetDoubleArray_28 = value; } + internal void* _GetChar16Array_29; + public delegate* unmanaged[Stdcall] GetChar16Array_29 { get => (delegate* unmanaged[Stdcall])_GetChar16Array_29; set => _GetChar16Array_29 = value; } + internal void* _GetBooleanArray_30; + public delegate* unmanaged[Stdcall] GetBooleanArray_30 { get => (delegate* unmanaged[Stdcall])_GetBooleanArray_30; set => _GetBooleanArray_30 = value; } + internal void* _GetStringArray_31; + public delegate* unmanaged[Stdcall] GetStringArray_31 { get => (delegate* unmanaged[Stdcall])_GetStringArray_31; set => _GetStringArray_31 = value; } + internal void* _GetInspectableArray_32; + public delegate* unmanaged[Stdcall] GetInspectableArray_32 { get => (delegate* unmanaged[Stdcall])_GetInspectableArray_32; set => _GetInspectableArray_32 = value; } + internal void* _GetGuidArray_33; + public delegate* unmanaged[Stdcall] GetGuidArray_33 { get => (delegate* unmanaged[Stdcall])_GetGuidArray_33; set => _GetGuidArray_33 = value; } + internal void* _GetDateTimeArray_34; + public delegate* unmanaged[Stdcall] GetDateTimeArray_34 { get => (delegate* unmanaged[Stdcall])_GetDateTimeArray_34; set => _GetDateTimeArray_34 = value; } + internal void* _GetTimeSpanArray_35; + public delegate* unmanaged[Stdcall] GetTimeSpanArray_35 { get => (delegate* unmanaged[Stdcall])_GetTimeSpanArray_35; set => _GetTimeSpanArray_35 = value; } + internal void* _GetPointArray_36; + public delegate* unmanaged[Stdcall] GetPointArray_36 { get => (delegate* unmanaged[Stdcall])_GetPointArray_36; set => _GetPointArray_36 = value; } + internal void* _GetSizeArray_37; + public delegate* unmanaged[Stdcall] GetSizeArray_37 { get => (delegate* unmanaged[Stdcall])_GetSizeArray_37; set => _GetSizeArray_37 = value; } + internal void* _GetRectArray_38; + public delegate* unmanaged[Stdcall] GetRectArray_38 { get => (delegate* unmanaged[Stdcall])_GetRectArray_38; set => _GetRectArray_38 = value; } + } + } +} From c8299c07e1b8ca16c4618c70ff7561110b78e56b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jan 2025 15:47:55 -0800 Subject: [PATCH 08/18] Update MatchingRefApiCompatBaseline.net8.0.txt --- src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt index 46d581fdcb..8a3a683f0d 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt @@ -9,4 +9,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.NullableAttri CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.NullableContextAttribute' exists on 'WinRT.EventRegistrationTokenTable.AddEventHandler(T)' in the implementation but not the reference. TypesMustExist : Type 'WinRT.DynamicWindowsRuntimeCastAttribute' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.Guid WinRT.Interop.IID.IID_IWeakReferenceSource.get()' does not exist in the reference but it does exist in the implementation. -Total Issues: 10 +CannotRemoveAttribute : Attribute 'System.ComponentModel.EditorBrowsableAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. +Total Issues: 13 From db42d35486a15870b362c897b7c644be38813351 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jan 2025 22:51:24 -0800 Subject: [PATCH 09/18] Fix some warnings --- src/WinRT.Runtime/Projections/IReferenceArray.net5.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs index 4766bdbead..5d12323606 100644 --- a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs +++ b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using WinRT; @@ -107,6 +108,10 @@ private static (int, IntPtr) FromManagedArray(T[] items) } } + // This type is only used in JIT scenarios, as all well known types supported for AOT use specialized 'IReferenceArray' implementations +#if NET + [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] +#endif [Guid("61C17707-2D65-11E0-9AE8-D48564015472")] internal sealed class IReferenceArray : global::Windows.Foundation.IReferenceArray { From 871652b42f7e41a8b287172d31aff80ec2a74c3d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 29 Jan 2025 22:57:27 -0800 Subject: [PATCH 10/18] Fix new AOT warnings --- src/WinRT.Runtime/Marshalers.cs | 17 +++++++++-------- .../MatchingRefApiCompatBaseline.net8.0.txt | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index 4f35ee3415..ede5581c2c 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -1072,6 +1072,9 @@ private static Type GetAbiType() public struct MarshalerArray { +#if NET + [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "'MarshalerArray' is only initialized from 'CreateMarshalerArray', which is not supported on AOT.")] +#endif public void Dispose() { if (_marshalers != null) @@ -1115,7 +1118,6 @@ public void Dispose() #else Marshal.SizeOf(AbiType); #endif -#pragma warning restore IL3050 var byte_length = length * abi_element_size; m._array = Marshal.AllocCoTaskMem(byte_length); m._marshalers = new object[length]; @@ -1126,6 +1128,7 @@ public void Dispose() Marshaler.CopyAbi(m._marshalers[i], (IntPtr)element); element += abi_element_size; } +#pragma warning restore IL3050 success = true; return m; } @@ -1178,10 +1181,10 @@ public void Dispose() #else Marshal.PtrToStructure((IntPtr)data, AbiType); #endif -#pragma warning restore IL3050 array[i] = Marshaler.FromAbi(abi_element); data += abi_element_size; } +#pragma warning restore IL3050 return array; } @@ -1214,10 +1217,10 @@ public static unsafe void CopyAbiArray(T[] array, object box) #else Marshal.PtrToStructure((IntPtr)data, AbiType); #endif -#pragma warning restore IL3050 array[i] = Marshaler.FromAbi(abi_element); data += abi_element_size; } +#pragma warning restore IL3050 } public static new unsafe (int length, IntPtr data) FromManagedArray(T[] array) @@ -1245,7 +1248,6 @@ public static unsafe void CopyAbiArray(T[] array, object box) #else Marshal.SizeOf(AbiType); #endif -#pragma warning restore IL3050 var byte_length = length * abi_element_size; data = Marshal.AllocCoTaskMem(byte_length); var bytes = (byte*)data.ToPointer(); @@ -1254,6 +1256,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) Marshaler.CopyManaged(array[i], (IntPtr)bytes); bytes += abi_element_size; } +#pragma warning restore IL3050 success = true; return (i, data); } @@ -1291,14 +1294,13 @@ public static unsafe void CopyManagedArray(T[] array, IntPtr data) #else Marshal.SizeOf(AbiType); #endif -#pragma warning restore IL3050 - var byte_length = length * abi_element_size; var bytes = (byte*)data.ToPointer(); for (i = 0; i < length; i++) { Marshaler.CopyManaged(array[i], (IntPtr)bytes); bytes += abi_element_size; } +#pragma warning restore IL3050 success = true; } finally @@ -1336,10 +1338,9 @@ public static unsafe void DisposeAbiArrayElements((int length, IntPtr data) abi) #else Marshal.PtrToStructure((IntPtr)data, AbiType); #endif -#pragma warning restore IL3050 - Marshaler.DisposeAbi(abi_element); data += abi_element_size; } +#pragma warning restore IL3050 } public static new unsafe void DisposeAbiArray(object box) diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt index 8a3a683f0d..4f87f18456 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt @@ -11,4 +11,5 @@ TypesMustExist : Type 'WinRT.DynamicWindowsRuntimeCastAttribute' does not exist MembersMustExist : Member 'public System.Guid WinRT.Interop.IID.IID_IWeakReferenceSource.get()' does not exist in the reference but it does exist in the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.EditorBrowsableAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'WinRT.MarshalNonBlittable.MarshalerArray.Dispose()' in the implementation but not the reference. Total Issues: 13 From 1d94b98ec6d5bab37a68b08967e4485c3fc6b326 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 30 Jan 2025 11:23:04 -0800 Subject: [PATCH 11/18] Use specialized marshallers for generic instantiations --- .../WinRT.SourceGenerator/AotOptimizer.cs | 39 ++++++++++++++++++- .../Extensions/SymbolExtensions.cs | 23 +++++++++++ .../GenericVtableInitializerStrings.cs | 30 +++++++++----- src/Authoring/WinRT.SourceGenerator/Helper.cs | 11 +++++- 4 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs index eecf23420e..d6210a7d93 100644 --- a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs +++ b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs @@ -741,7 +741,8 @@ genericParameter is INamedTypeSymbol genericParameterIface && genericParameters.Add(new GenericParameter( ToFullyQualifiedString(genericParameter), GeneratorHelper.GetAbiType(genericParameter, mapper), - isNullable ? TypeKind.Interface : genericParameter.TypeKind)); + isNullable ? TypeKind.Interface : genericParameter.TypeKind, + ComputeTypeFlags(genericParameter, compilation))); } genericInterfacesToAddToVtable.Add(new GenericInterface( @@ -774,6 +775,25 @@ void CheckForInterfaceToUseForRuntimeClassName(INamedTypeSymbol iface) } } + private static TypeFlags ComputeTypeFlags(ITypeSymbol symbol, Compilation compilation) + { + TypeFlags typeFlags = TypeFlags.None; + + // Check for exception types + if (symbol.TypeKind is TypeKind.Class) + { + var exceptionType = compilation.GetTypeByMetadataName("System.Exception")!; + + if (SymbolEqualityComparer.Default.Equals(symbol, exceptionType) || + symbol.InheritsFromType(exceptionType)) + { + typeFlags |= TypeFlags.Exception; + } + } + + return typeFlags; + } + private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, TypeMapper mapper, Stack typeStack, Func isWinRTType, INamedTypeSymbol objectType, out IList compatibleTypes) { compatibleTypes = null; @@ -1919,7 +1939,8 @@ namespace {{bindableCustomProperties.Namespace}} internal readonly record struct GenericParameter( string ProjectedType, string AbiType, - TypeKind TypeKind); + TypeKind TypeKind, + TypeFlags TypeFlags); internal readonly record struct GenericInterface( string Interface, @@ -1969,6 +1990,20 @@ internal readonly record struct CsWinRTAotOptimizerProperties( bool IsCsWinRTCcwLookupTableGeneratorEnabled, bool IsCsWinRTAotOptimizerInAutoMode); + /// + /// Additional flags for discovered types. + /// + [Flags] + internal enum TypeFlags + { + None = 0x0, + + /// + /// The type derives from . + /// + Exception = 0x1 << 0 + } + /// /// A model describing a type info in a type hierarchy. /// diff --git a/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs b/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs index e7caf4019b..681ff5f8fd 100644 --- a/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs +++ b/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs @@ -115,4 +115,27 @@ public static bool IsAccessibleFromCompilationAssembly(this ISymbol symbol, Comp { return compilation.IsSymbolAccessibleWithin(symbol, compilation.Assembly); } + + /// + /// Checks whether or not a given inherits from a specified type. + /// + /// The target instance to check. + /// The instane to check for inheritance from. + /// Whether or not inherits from . + public static bool InheritsFromType(this ITypeSymbol typeSymbol, ITypeSymbol baseTypeSymbol) + { + INamedTypeSymbol? currentBaseTypeSymbol = typeSymbol.BaseType; + + while (currentBaseTypeSymbol is not null) + { + if (SymbolEqualityComparer.Default.Equals(currentBaseTypeSymbol, baseTypeSymbol)) + { + return true; + } + + currentBaseTypeSymbol = currentBaseTypeSymbol.BaseType; + } + + return false; + } } diff --git a/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs b/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs index fe2fb8b98f..d2c95eaf6a 100644 --- a/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs +++ b/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs @@ -18,11 +18,19 @@ public static string GetInstantiation(string genericInterface, EquatableArray.Abi_GetMany_3(thisPtr, ref __items); - {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind)}}.CopyManagedArray(__items, items); + {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind, typeFlags)}}.CopyManagedArray(__items, items); *__return_value__ = ____return_value__; } catch (global::System.Exception __exception__) @@ -326,7 +338,7 @@ private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* __return return iEnumeratorInstantiation; } - private static string GetIListInstantiation(string genericType, string abiType, TypeKind typeKind) + private static string GetIListInstantiation(string genericType, string abiType, TypeKind typeKind, TypeFlags typeFlags) { string iListInstantiation = $$""" internal static class IList_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} @@ -513,7 +525,7 @@ private static unsafe int Do_Abi_GetMany_10(IntPtr thisPtr, uint startIndex, int try { ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_GetMany_10(thisPtr, startIndex, ref __items); - {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind)}}.CopyManagedArray(__items, items); + {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind, typeFlags)}}.CopyManagedArray(__items, items); *__return_value__ = ____return_value__; } catch (global::System.Exception __exception__) @@ -563,7 +575,7 @@ private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* __return_value return iListInstantiation; } - private static string GetIReadOnlyListInstantiation(string genericType, string abiType, TypeKind typeKind) + private static string GetIReadOnlyListInstantiation(string genericType, string abiType, TypeKind typeKind, TypeFlags typeFlags) { string iReadOnlylistInstantiation = $$""" internal static class IReadOnlyList_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} @@ -633,7 +645,7 @@ private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, uint startIndex, int try { ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_GetMany_3(thisPtr, startIndex, ref __items); - {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind)}}.CopyManagedArray(__items, items); + {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind, typeFlags)}}.CopyManagedArray(__items, items); *__return_value__ = ____return_value__; } catch (global::System.Exception __exception__) diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index 9934a740a0..d6626c5c80 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -1064,8 +1064,17 @@ public static string GetFromManagedMarshaler(string type, string abiType, TypeKi } } - public static string GetCopyManagedArrayMarshaler(string type, string abiType, TypeKind kind) + public static string GetCopyManagedArrayMarshaler(string type, string abiType, TypeKind kind, TypeFlags typeFlags) { + if (type is "System.String") return "global::WinRT.MarshalString"; + if (type is "System.Type") return "global::ABI.System.Type"; + if (type is "System.Object") return "global::WinRT.MarshalInspectable"; + + if (typeFlags.HasFlag(TypeFlags.Exception)) + { + return "global::WinRT.MarshalNonBlittable.CopyManagedArray"; + } + if (kind == TypeKind.Class || kind == TypeKind.Delegate) { // TODO: Classes and delegates are missing CopyManagedArray. From 0fd41c2b05c0753f19845b53f3edaee5994ad002 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 30 Jan 2025 13:30:16 -0800 Subject: [PATCH 12/18] Fix more generic instantiation cases --- src/Authoring/WinRT.SourceGenerator/Helper.cs | 22 +++++++++---------- src/WinRT.Runtime/Marshalers.cs | 14 ++++++++++-- .../MatchingRefApiCompatBaseline.net8.0.txt | 3 ++- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index d6626c5c80..030bae43ea 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -1066,19 +1066,19 @@ public static string GetFromManagedMarshaler(string type, string abiType, TypeKi public static string GetCopyManagedArrayMarshaler(string type, string abiType, TypeKind kind, TypeFlags typeFlags) { - if (type is "System.String") return "global::WinRT.MarshalString"; - if (type is "System.Type") return "global::ABI.System.Type"; - if (type is "System.Object") return "global::WinRT.MarshalInspectable"; - - if (typeFlags.HasFlag(TypeFlags.Exception)) - { - return "global::WinRT.MarshalNonBlittable.CopyManagedArray"; - } - if (kind == TypeKind.Class || kind == TypeKind.Delegate) { - // TODO: Classes and delegates are missing CopyManagedArray. - return $$"""Marshaler<{{type}}>"""; + if (type is "System.String") return "global::WinRT.MarshalString"; + if (type is "System.Type") return "global::ABI.System.Type"; + if (type is "System.Object") return "global::WinRT.MarshalInspectable"; + + if (typeFlags.HasFlag(TypeFlags.Exception)) + { + return "global::WinRT.MarshalNonBlittable"; + } + + // Handles all other classes and delegate types + return $"global::WinRT.MarshalGenericHelper<{type}>"; } else { diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index ede5581c2c..72e8621f0e 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -991,7 +991,17 @@ public void DisposeAbiArray(object arg) } } - internal static class MarshalGenericHelper + /// + /// This type is only meant to be used by generated marshalling stubs. Its API surface might change in the future. + /// + /// The managed type to marshal. + [EditorBrowsable(EditorBrowsableState.Never)] +#if EMBED + internal +#else + public +#endif + static class MarshalGenericHelper { private static unsafe void CopyManagedFallback(T value, IntPtr dest) { @@ -1007,7 +1017,7 @@ private static unsafe void CopyManagedFallback(T value, IntPtr dest) } } - internal static unsafe void CopyManagedArray(T[] array, IntPtr data) => MarshalInterfaceHelper.CopyManagedArray(array, data, MarshalGeneric.CopyManaged ?? CopyManagedFallback); + public static unsafe void CopyManagedArray(T[] array, IntPtr data) => MarshalInterfaceHelper.CopyManagedArray(array, data, MarshalGeneric.CopyManaged ?? CopyManagedFallback); } #if EMBED diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt index 4f87f18456..100f0bef76 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt @@ -12,4 +12,5 @@ MembersMustExist : Member 'public System.Guid WinRT.Interop.IID.IID_IWeakReferen CannotRemoveAttribute : Attribute 'System.ComponentModel.EditorBrowsableAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'WinRT.MarshalNonBlittable.MarshalerArray.Dispose()' in the implementation but not the reference. -Total Issues: 13 +TypesMustExist : Type 'WinRT.MarshalGenericHelper' does not exist in the reference but it does exist in the implementation. +Total Issues: 14 From 84d41e9d55d464921da23b050877a8d790d3c6cf Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 30 Jan 2025 15:46:05 -0800 Subject: [PATCH 13/18] Make 'Marshaler' obsolete --- src/WinRT.Runtime/Marshalers.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index 72e8621f0e..3212c70c56 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -75,7 +75,7 @@ public static unsafe ref readonly char GetPinnableReference(this string str) #if EMBED internal -#else +#else public #endif class MarshalString @@ -107,7 +107,7 @@ public Pinnable(string value) _header = default; #if DEBUG _pinned = false; -#endif +#endif } public ref readonly char GetPinnableReference() @@ -2028,6 +2028,7 @@ public static T FromAbi(IntPtr nativeDelegate) } } + [Obsolete("This type should only be used internally by 'Marshaler'.")] internal static class Marshaler { internal static readonly Func ReturnParameterFunc = ReturnParameter; From b6dd9d88fa2133e2badb58e289692b2daaf79806 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 30 Jan 2025 19:29:02 -0800 Subject: [PATCH 14/18] Fix ILC warnings on 'IReferenceArray' --- .../Projections/IReferenceArray.net5.cs | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs index 5d12323606..bebd1dbf25 100644 --- a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs +++ b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs @@ -108,10 +108,9 @@ private static (int, IntPtr) FromManagedArray(T[] items) } } - // This type is only used in JIT scenarios, as all well known types supported for AOT use specialized 'IReferenceArray' implementations -#if NET - [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] -#endif + // This type is only used in JIT scenarios, as all well known types supported for AOT use specialized 'IReferenceArray' implementations. + // We can't add '[RequiresDynamicCode]' on this type, as it's indirectly rooted by the interface type. Because it's never actually used + // on AOT, we can just guard each AOT-unsafe code path with a feature check, and throw if on AOT. That avoids ILC warnings. [Guid("61C17707-2D65-11E0-9AE8-D48564015472")] internal sealed class IReferenceArray : global::Windows.Foundation.IReferenceArray { @@ -127,6 +126,14 @@ public static ObjectReferenceValue CreateMarshaler2(object value) => public static object FromAbi(IntPtr ptr) { +#if NET + // This path is unreachable on AOT, but this helps ILC + if (!RuntimeFeature.IsDynamicCodeSupported) + { + throw new NotSupportedException("'IReferenceArray' is not supported in AOT environments."); + } +#endif + if (ptr == IntPtr.Zero) { return null; @@ -138,9 +145,18 @@ public static object FromAbi(IntPtr ptr) public static unsafe object GetValue(IInspectable inspectable) { +#if NET + // This path is unreachable on AOT, but this fixes some ILC warnings + if (!RuntimeFeature.IsDynamicCodeSupported) + { + throw new NotSupportedException("'IReferenceArray' is not supported in AOT environments."); + } +#endif + IntPtr referenceArrayPtr = IntPtr.Zero; int __retval_length = default; IntPtr __retval_data = default; +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 try { ExceptionHelpers.ThrowExceptionForHR( @@ -159,6 +175,7 @@ public static unsafe object GetValue(IInspectable inspectable) Marshaler.DisposeAbiArray((__retval_length, __retval_data)); MarshalExtensions.ReleaseIfNotNull(referenceArrayPtr); } +#pragma warning disable IL3050 } public static unsafe void CopyManaged(object o, IntPtr dest) @@ -194,8 +211,17 @@ public unsafe T[] Value { get { +#if NET + // This path is unreachable on AOT, but this fixes some ILC warnings + if (!RuntimeFeature.IsDynamicCodeSupported) + { + throw new NotSupportedException("'IReferenceArray' is not supported in AOT environments."); + } +#endif + int __retval_length = default; IntPtr __retval_data = default; +#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 try { ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval_length, &__retval_data)); @@ -206,6 +232,7 @@ public unsafe T[] Value { Marshaler.DisposeAbiArray((__retval_length, __retval_data)); } +#pragma warning restore IL3050 } } } From 9aa9384f1f952b4afb928559a3ada52533569fdc Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 3 Feb 2025 14:14:08 -0800 Subject: [PATCH 15/18] Remove '[RequiresDynamicCode]' from 'Marshaler' --- src/WinRT.Runtime/Marshalers.cs | 1 - src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index 3212c70c56..b03fbb3107 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -2050,7 +2050,6 @@ internal static class Marshaler #if NET [EditorBrowsable(EditorBrowsableState.Never)] - [RequiresDynamicCode(AttributeMessages.NotSupportedIfDynamicCodeIsNotAvailable)] #endif #if EMBED internal diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt index 100f0bef76..9787c647dd 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt @@ -10,7 +10,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.NullableConte TypesMustExist : Type 'WinRT.DynamicWindowsRuntimeCastAttribute' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.Guid WinRT.Interop.IID.IID_IWeakReferenceSource.get()' does not exist in the reference but it does exist in the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.EditorBrowsableAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. -CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'WinRT.MarshalNonBlittable.MarshalerArray.Dispose()' in the implementation but not the reference. TypesMustExist : Type 'WinRT.MarshalGenericHelper' does not exist in the reference but it does exist in the implementation. -Total Issues: 14 +Total Issues: 13 From f7616223dbdd2b46c78ee680e493e75d41466c6f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 24 Feb 2025 18:02:24 -0800 Subject: [PATCH 16/18] Remove unnecessary '[Obsolete]' attribute --- src/WinRT.Runtime/Marshalers.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index b03fbb3107..cac7ba89df 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -2028,7 +2028,6 @@ public static T FromAbi(IntPtr nativeDelegate) } } - [Obsolete("This type should only be used internally by 'Marshaler'.")] internal static class Marshaler { internal static readonly Func ReturnParameterFunc = ReturnParameter; From dc7feb296333312face8a18eb3a9edcc9a76c4ab Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 12 Mar 2025 10:08:58 -0700 Subject: [PATCH 17/18] Tweak AOT checks --- src/WinRT.Runtime/Marshalers.cs | 13 +++++-------- .../MatchingRefApiCompatBaseline.net8.0.txt | 3 +-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index cac7ba89df..4c8064d0b7 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -1082,9 +1082,6 @@ private static Type GetAbiType() public struct MarshalerArray { -#if NET - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "'MarshalerArray' is only initialized from 'CreateMarshalerArray', which is not supported on AOT.")] -#endif public void Dispose() { if (_marshalers != null) @@ -1106,7 +1103,7 @@ public void Dispose() public static new unsafe MarshalerArray CreateMarshalerArray(T[] array) { -#if NET && !NET9_0_OR_GREATER +#if NET if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1159,7 +1156,7 @@ public void Dispose() public static new unsafe T[] FromAbiArray(object box) { -#if NET && !NET9_0_OR_GREATER +#if NET if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1200,7 +1197,7 @@ public void Dispose() public static unsafe void CopyAbiArray(T[] array, object box) { -#if NET && !NET9_0_OR_GREATER +#if NET if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1235,7 +1232,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) public static new unsafe (int length, IntPtr data) FromManagedArray(T[] array) { -#if NET && !NET9_0_OR_GREATER +#if NET if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1281,7 +1278,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) public static unsafe void CopyManagedArray(T[] array, IntPtr data) { -#if NET && !NET9_0_OR_GREATER +#if NET if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt index 9787c647dd..8c5a381129 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt @@ -10,6 +10,5 @@ CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.NullableConte TypesMustExist : Type 'WinRT.DynamicWindowsRuntimeCastAttribute' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.Guid WinRT.Interop.IID.IID_IWeakReferenceSource.get()' does not exist in the reference but it does exist in the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.EditorBrowsableAttribute' exists on 'WinRT.Marshaler' in the implementation but not the reference. -CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'WinRT.MarshalNonBlittable.MarshalerArray.Dispose()' in the implementation but not the reference. TypesMustExist : Type 'WinRT.MarshalGenericHelper' does not exist in the reference but it does exist in the implementation. -Total Issues: 13 +Total Issues: 12 From 46364a943cf6e4e78a1d508e9319a5d9956712a1 Mon Sep 17 00:00:00 2001 From: Manodasan Wignarajah Date: Wed, 16 Jul 2025 11:53:24 -0700 Subject: [PATCH 18/18] Fix non-blittable array marshaling (#2016) * Fix non bittable array marshaling * Move AOT tests to .NET 9 * Fix enums * Fix for .NET 9 * PR feedback --- .../CsWinRT-FunctionalTest-Steps.yml | 12 +-- src/Directory.Build.props | 2 +- .../FunctionalTests/Collections/Program.cs | 79 +++++++++++++++++++ .../JsonValueFunctionCalls.csproj | 2 +- .../JsonValueFunctionCalls/Program.cs | 18 +++-- src/WinRT.Runtime/Marshalers.cs | 53 ++++++++++--- 6 files changed, 140 insertions(+), 26 deletions(-) diff --git a/build/AzurePipelineTemplates/CsWinRT-FunctionalTest-Steps.yml b/build/AzurePipelineTemplates/CsWinRT-FunctionalTest-Steps.yml index 5ae79362d0..b742f26954 100644 --- a/build/AzurePipelineTemplates/CsWinRT-FunctionalTest-Steps.yml +++ b/build/AzurePipelineTemplates/CsWinRT-FunctionalTest-Steps.yml @@ -62,20 +62,20 @@ steps: TargetFolder: $(StagingFolder)\FunctionalTests\${{ functionalTest }}\ - task: MSBuild@1 - displayName: Publish ${{ functionalTest }} for AOT (net8.0) + displayName: Publish ${{ functionalTest }} for AOT (net9.0) condition: and(succeeded(), and(eq(variables['BuildConfiguration'], 'release'), eq(variables['BuildPlatform'], 'x64'))) inputs: solution: $(Build.SourcesDirectory)\src\Tests\FunctionalTests\${{ functionalTest }}\${{ functionalTest }}.csproj - msbuildArguments: /t:publish /p:CIBuildReason=CI,RuntimeIdentifier=win-$(BuildPlatform),TargetFramework=net8.0,solutiondir=$(Build.SourcesDirectory)\src\,VersionNumber=$(VersionNumber),VersionString=$(Build.BuildNumber),AssemblyVersionNumber=$(WinRT.Runtime.AssemblyVersion),GenerateTestProjection=true,AllowedReferenceRelatedFileExtensions=".xml;.pri;.dll.config;.exe.config" + msbuildArguments: /t:publish /p:CIBuildReason=CI,RuntimeIdentifier=win-$(BuildPlatform),TargetFramework=net9.0,solutiondir=$(Build.SourcesDirectory)\src\,VersionNumber=$(VersionNumber),VersionString=$(Build.BuildNumber),AssemblyVersionNumber=$(WinRT.Runtime.AssemblyVersion),GenerateTestProjection=true,AllowedReferenceRelatedFileExtensions=".xml;.pri;.dll.config;.exe.config" platform: $(BuildPlatform) configuration: $(BuildConfiguration) - task: CmdLine@2 - displayName: Run ${{ functionalTest }} for AOT (net8.0) + displayName: Run ${{ functionalTest }} for AOT (net9.0) condition: and(succeeded(), and(eq(variables['BuildConfiguration'], 'release'), eq(variables['BuildPlatform'], 'x64'))) continueOnError: True inputs: - workingDirectory: $(Build.SourcesDirectory)\src\Tests\FunctionalTests\${{ functionalTest }}\bin\$(BuildConfiguration)\net8.0\win-$(BuildPlatform)\publish + workingDirectory: $(Build.SourcesDirectory)\src\Tests\FunctionalTests\${{ functionalTest }}\bin\$(BuildConfiguration)\net9.0\win-$(BuildPlatform)\publish script: | dir echo Running ${{ functionalTest }}.exe @@ -86,8 +86,8 @@ steps: exit /b 0 - task: CopyFiles@2 - displayName: Copy ${{ functionalTest }} for AOT (net8.0) + displayName: Copy ${{ functionalTest }} for AOT (net9.0) condition: and(eq(variables['_PublishFunctionalTests'], 'true'), and(eq(variables['BuildConfiguration'], 'release'), eq(variables['BuildPlatform'], 'x64'))) inputs: - SourceFolder: $(Build.SourcesDirectory)\src\Tests\FunctionalTests\${{ functionalTest }}\bin\$(BuildConfiguration)\net8.0\win-$(BuildPlatform)\publish + SourceFolder: $(Build.SourcesDirectory)\src\Tests\FunctionalTests\${{ functionalTest }}\bin\$(BuildConfiguration)\net9.0\win-$(BuildPlatform)\publish TargetFolder: $(StagingFolder)\FunctionalTests\${{ functionalTest }}\ diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 59c8ce0679..6becbb3232 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -35,7 +35,7 @@ net8.0;net9.0 net8.0-windows10.0.19041.0 net8.0-windows10.0.19041.0 - net8.0 + net8.0;net9.0 false high diff --git a/src/Tests/FunctionalTests/Collections/Program.cs b/src/Tests/FunctionalTests/Collections/Program.cs index 6ff5f36699..b710477e4b 100644 --- a/src/Tests/FunctionalTests/Collections/Program.cs +++ b/src/Tests/FunctionalTests/Collections/Program.cs @@ -6,6 +6,7 @@ using System.Threading; using test_component_derived.Nested; using TestComponentCSharp; +using Windows.Foundation; var instance = new Class(); @@ -40,6 +41,84 @@ return 101; } +string[] stringArr = new string[] { "apples", "oranges", "pears" }; +string[] stringArr2 = new string[stringArr.Length]; +string[] outStringArr; +string[] retStringArr = instance2.Array12(stringArr, stringArr2, out outStringArr); +if (!AllEqual(stringArr, stringArr2, outStringArr, retStringArr)) +{ + return 101; +} + +TestComponent.Blittable[] blittableArr = new TestComponent.Blittable[] { + new TestComponent.Blittable(1, 2, 3, 4, -5, -6, -7, 8.0f, 9.0, typeof(TestComponent.ITests).GUID), + new TestComponent.Blittable(10, 20, 30, 40, -50, -60, -70, 80.0f, 90.0, typeof(IStringable).GUID) + }; +TestComponent.Blittable[] blittableArr2 = new TestComponent.Blittable[blittableArr.Length]; +TestComponent.Blittable[] outBlittableArr; +TestComponent.Blittable[] retBlittableArr = instance2.Array13(blittableArr, blittableArr2, out outBlittableArr); +if (!AllEqual(blittableArr, blittableArr2, outBlittableArr, retBlittableArr)) +{ + return 101; +} + +#if NET9_0_OR_GREATER + +TestComponent.NonBlittable[] nonBlittableArr = new TestComponent.NonBlittable[] { + new TestComponent.NonBlittable(false, 'X', "First", (long?)PropertyValue.CreateInt64(123)), + new TestComponent.NonBlittable(true, 'Y', "Second", (long?)PropertyValue.CreateInt64(456)), + new TestComponent.NonBlittable(false, 'Z', "Third", (long?)PropertyValue.CreateInt64(789)) + }; +TestComponent.NonBlittable[] nonBlittableArr2 = new TestComponent.NonBlittable[nonBlittableArr.Length]; +TestComponent.NonBlittable[] outNonBlittableArr; +TestComponent.NonBlittable[] retNonBlittableArr = instance2.Array14(nonBlittableArr, nonBlittableArr2, out outNonBlittableArr); +if (!AllEqual(nonBlittableArr, nonBlittableArr2, outNonBlittableArr, retNonBlittableArr)) +{ + return 101; +} + +TestComponent.Nested[] nestedArr = new TestComponent.Nested[]{ + new TestComponent.Nested( + new TestComponent.Blittable(1, 2, 3, 4, -5, -6, -7, 8.0f, 9.0, typeof(TestComponent.ITests).GUID), + new TestComponent.NonBlittable(false, 'X', "First", (long?)PropertyValue.CreateInt64(123))), + new TestComponent.Nested( + new TestComponent.Blittable(10, 20, 30, 40, -50, -60, -70, 80.0f, 90.0, typeof(IStringable).GUID), + new TestComponent.NonBlittable(true, 'Y', "Second", (long?)PropertyValue.CreateInt64(456))), + new TestComponent.Nested( + new TestComponent.Blittable(1, 2, 3, 4, -5, -6, -7, 8.0f, 9.0, typeof(WinRT.IInspectable).GUID), + new TestComponent.NonBlittable(false, 'Z', "Third", (long?)PropertyValue.CreateInt64(789))) + }; +TestComponent.Nested[] nestedArr2 = new TestComponent.Nested[nestedArr.Length]; +TestComponent.Nested[] outNestedArr; +TestComponent.Nested[] retNestedArr = instance2.Array15(nestedArr, nestedArr2, out outNestedArr); +if (!AllEqual(nestedArr, nestedArr2, outNestedArr, retNestedArr)) +{ + return 101; +} + +EnumValue[] enumArr = new EnumValue[] { EnumValue.One, EnumValue.Two }; +instance.EnumsProperty = enumArr; +EnumValue[] retEnumArr = instance.EnumsProperty; +if (!AllEqual(enumArr, retEnumArr)) +{ + return 101; +} + +#endif + +IStringable[] stringableArr = new IStringable[] { + Windows.Data.Json.JsonValue.CreateNumberValue(3), + Windows.Data.Json.JsonValue.CreateNumberValue(4), + Windows.Data.Json.JsonValue.CreateNumberValue(5.0) + }; +IStringable[] stringableArr2 = new IStringable[stringableArr.Length]; +IStringable[] outStringableArr; +IStringable[] retStringableArr = instance2.Array16(stringableArr, stringableArr2, out outStringableArr); +if (!AllEqual(stringableArr, stringableArr2, outStringableArr, retStringableArr)) +{ + return 101; +} + var hierarchyDAsObjectList = HierarchyC.CreateDerivedHierarchyDAsObjectList(); foreach (var hierarchyDAsObject in hierarchyDAsObjectList) { diff --git a/src/Tests/FunctionalTests/JsonValueFunctionCalls/JsonValueFunctionCalls.csproj b/src/Tests/FunctionalTests/JsonValueFunctionCalls/JsonValueFunctionCalls.csproj index f65cc8b91b..df41ced1b3 100644 --- a/src/Tests/FunctionalTests/JsonValueFunctionCalls/JsonValueFunctionCalls.csproj +++ b/src/Tests/FunctionalTests/JsonValueFunctionCalls/JsonValueFunctionCalls.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/Tests/FunctionalTests/JsonValueFunctionCalls/Program.cs b/src/Tests/FunctionalTests/JsonValueFunctionCalls/Program.cs index dbe1054435..2d47eb4aa3 100644 --- a/src/Tests/FunctionalTests/JsonValueFunctionCalls/Program.cs +++ b/src/Tests/FunctionalTests/JsonValueFunctionCalls/Program.cs @@ -19,10 +19,16 @@ // Class function call result += (int)(a[1] as Windows.Data.Json.JsonValue).GetNumber(); -var enumVal = TestComponentCSharp.Class.BoxedEnum; -if (enumVal is TestComponentCSharp.EnumValue val && val == TestComponentCSharp.EnumValue.Two) -{ - result += 1; -} +CheckBoxedEnum(); -return result == 17 ? 100 : 101; \ No newline at end of file +return result == 17 ? 100 : 101; + +[WinRT.DynamicWindowsRuntimeCast(typeof(TestComponentCSharp.EnumValue))] +void CheckBoxedEnum() +{ + var enumVal = TestComponentCSharp.Class.BoxedEnum; + if (enumVal is TestComponentCSharp.EnumValue val && val == TestComponentCSharp.EnumValue.Two) + { + result += 1; + } +} \ No newline at end of file diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index 4c8064d0b7..ec6f3f1692 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -685,6 +685,32 @@ static MarshalGeneric() DisposeMarshaler = ABI.System.NonBlittableMarshallingStubs.NoOpFunc; DisposeAbi = ABI.System.NonBlittableMarshallingStubs.NoOpFunc; } + else if (typeof(T).IsEnum) + { + Func ReturnTypedParameterFunc = (T value) => value; + AbiType = typeof(T); + CreateMarshaler = ReturnTypedParameterFunc; + CreateMarshaler2 = CreateMarshaler; + GetAbi = Marshaler.ReturnParameterFunc; + FromAbi = (object value) => (T)value; + FromManaged = ReturnTypedParameterFunc; + DisposeMarshaler = ABI.System.NonBlittableMarshallingStubs.NoOpFunc; + DisposeAbi = ABI.System.NonBlittableMarshallingStubs.NoOpFunc; + if (typeof(T).IsEnum) + { + // For marshaling non-blittable enum arrays via MarshalNonBlittable + if (typeof(T).GetEnumUnderlyingType() == typeof(int)) + { + CopyAbi = Marshaler.CopyIntEnumFunc; + CopyManaged = Marshaler.CopyIntEnumDirectFunc.WithTypedT1(); + } + else + { + CopyAbi = Marshaler.CopyUIntEnumFunc; + CopyManaged = Marshaler.CopyUIntEnumDirectFunc.WithTypedT1(); + } + } + } else if (typeof(T).IsValueType) { // Value types can have custom marshaller types and use value types in places where we can't construct @@ -1088,7 +1114,10 @@ public void Dispose() { foreach (var marshaler in _marshalers) { - Marshaler.DisposeMarshaler(marshaler); + // We make use of MarshalNonBlittable for array marshaling when T is non-blittable or when it is an enum. + // Both scenarios are handled by MarshalNonBlittable for marshaling T itself, so we just directly use that + // here and below without needing to go through Marshaler. + MarshalNonBlittable.DisposeMarshaler(marshaler); } } if (_array != IntPtr.Zero) @@ -1103,7 +1132,7 @@ public void Dispose() public static new unsafe MarshalerArray CreateMarshalerArray(T[] array) { -#if NET +#if NET && !NET9_0_OR_GREATER if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1131,8 +1160,8 @@ public void Dispose() var element = (byte*)m._array.ToPointer(); for (int i = 0; i < length; i++) { - m._marshalers[i] = Marshaler.CreateMarshaler(array[i]); - Marshaler.CopyAbi(m._marshalers[i], (IntPtr)element); + m._marshalers[i] = MarshalNonBlittable.CreateMarshaler(array[i]); + MarshalNonBlittable.CopyAbi(m._marshalers[i], (IntPtr)element); element += abi_element_size; } #pragma warning restore IL3050 @@ -1156,7 +1185,7 @@ public void Dispose() public static new unsafe T[] FromAbiArray(object box) { -#if NET +#if NET && !NET9_0_OR_GREATER if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1188,7 +1217,7 @@ public void Dispose() #else Marshal.PtrToStructure((IntPtr)data, AbiType); #endif - array[i] = Marshaler.FromAbi(abi_element); + array[i] = MarshalNonBlittable.FromAbi(abi_element); data += abi_element_size; } #pragma warning restore IL3050 @@ -1197,7 +1226,7 @@ public void Dispose() public static unsafe void CopyAbiArray(T[] array, object box) { -#if NET +#if NET && !NET9_0_OR_GREATER if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1224,7 +1253,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) #else Marshal.PtrToStructure((IntPtr)data, AbiType); #endif - array[i] = Marshaler.FromAbi(abi_element); + array[i] = MarshalNonBlittable.FromAbi(abi_element); data += abi_element_size; } #pragma warning restore IL3050 @@ -1232,7 +1261,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) public static new unsafe (int length, IntPtr data) FromManagedArray(T[] array) { -#if NET +#if NET && !NET9_0_OR_GREATER if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1260,7 +1289,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) var bytes = (byte*)data.ToPointer(); for (i = 0; i < length; i++) { - Marshaler.CopyManaged(array[i], (IntPtr)bytes); + MarshalNonBlittable.CopyManaged(array[i], (IntPtr)bytes); bytes += abi_element_size; } #pragma warning restore IL3050 @@ -1278,7 +1307,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) public static unsafe void CopyManagedArray(T[] array, IntPtr data) { -#if NET +#if NET && !NET9_0_OR_GREATER if (!RuntimeFeature.IsDynamicCodeCompiled) { throw new NotSupportedException($"Cannot handle array marshalling for non blittable type '{typeof(T)}'."); @@ -1304,7 +1333,7 @@ public static unsafe void CopyManagedArray(T[] array, IntPtr data) var bytes = (byte*)data.ToPointer(); for (i = 0; i < length; i++) { - Marshaler.CopyManaged(array[i], (IntPtr)bytes); + MarshalNonBlittable.CopyManaged(array[i], (IntPtr)bytes); bytes += abi_element_size; } #pragma warning restore IL3050