Skip to content

Commit

Permalink
Stop rooting nested types for helper types (#1521)
Browse files Browse the repository at this point in the history
* Stop rooting nested types for helper types

* Improve fallback path for 'FindVftblType'

* Remove duplicate null check on vftbl types

* Fix assembly name and add more rooted types

* Update MatchingRefApiCompatBaseline.txt

* Fix repeated namespace in dynamic dependency

---------

Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com>
  • Loading branch information
Sergio0694 and manodasanW authored Mar 22, 2024
1 parent 3ad7e7e commit 46bb1b5
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 36 deletions.
3 changes: 2 additions & 1 deletion src/WinRT.Runtime/ApiCompatBaseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ CannotRemoveAttribute : Attribute 'WinRT.ObjectReferenceWrapperAttribute' exists
CannotRemoveAttribute : Attribute 'WinRT.ObjectReferenceWrapperAttribute' exists on 'WinRT.IInspectable' in the contract but not the implementation.
MembersMustExist : Member 'protected void Microsoft.UI.Xaml.LayoutCycleException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'protected void Microsoft.UI.Xaml.Automation.ElementNotAvailableException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
Total Issues: 122
CannotChangeAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' on 'WinRT.WindowsRuntimeHelperTypeAttribute.HelperType' changed from '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes)]' in the contract to '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)]' in the implementation.
Total Issues: 123
5 changes: 5 additions & 0 deletions src/WinRT.Runtime/AttributeMessages.net5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ internal static class AttributeMessages
/// </summary>
public const string GenericDeprecatedMessage = "This method is deprecated and will be removed in a future release.";

/// <summary>
/// Message for a generic annotation for a method using <see cref="System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute"/>.
/// </summary>
public const string GenericRequiresUnreferencedCodeMessage = "This method is not trim-safe, and is only supported for use when not using trimming (or AOT).";

/// <summary>
/// Message for marshalling or generic code requiring <see cref="System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute"/>.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/WinRT.Runtime/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ public WindowsRuntimeHelperTypeAttribute()

public WindowsRuntimeHelperTypeAttribute(
#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType)
{
HelperType = helperType;
}

#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public Type HelperType { get; }
}
Expand Down
1 change: 0 additions & 1 deletion src/WinRT.Runtime/ComWrappersSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ public static void RegisterHelperType(
Type type,
#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType) => TypeExtensions.HelperTypeCache.TryAdd(type, helperType);
Expand Down
2 changes: 0 additions & 2 deletions src/WinRT.Runtime/Marshalers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1375,15 +1375,13 @@ struct MarshalInterface<T>
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicFields |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicMethods)]
#endif
private static Type _HelperType;

#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicFields |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicMethods)]
#endif
private static Type HelperType => _HelperType ??= typeof(T).GetHelperType();
Expand Down
4 changes: 3 additions & 1 deletion src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,6 @@ TypesMustExist : Type 'ABI.WinRT.Interop.EventSource<TDelegate>' does not exist
TypesMustExist : Type 'ABI.WinRT.Interop.EventSourceState<TDelegate>' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'ABI.WinRT.Interop.EventHandlerEventSource' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'ABI.WinRT.Interop.EventHandlerEventSource<T>' does not exist in the reference but it does exist in the implementation.
Total Issues: 217
CannotChangeAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' on 'WinRT.WindowsRuntimeHelperTypeAttribute.HelperType' changed from '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)]' in the implementation to '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes)]' in the reference.
CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'WinRT.TypeExtensions.FindVftblType(System.Type)' in the implementation but not the reference.
Total Issues: 219
7 changes: 0 additions & 7 deletions src/WinRT.Runtime/Projections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ private static void RegisterCustomAbiTypeMapping(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType,
Expand All @@ -143,7 +142,6 @@ private static void RegisterCustomTypeToHelperTypeMapping(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType)
Expand All @@ -164,7 +162,6 @@ private static void RegisterCustomTypeToHelperTypeMappingNoLock(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type helperType)
Expand All @@ -177,7 +174,6 @@ private static void RegisterCustomAbiTypeMappingNoLock(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType,
Expand All @@ -200,7 +196,6 @@ private static void RegisterCustomAbiTypeMapping(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType)
Expand All @@ -221,7 +216,6 @@ private static void RegisterCustomAbiTypeMappingNoLock(
#if NET
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
Type abiType)
Expand All @@ -233,7 +227,6 @@ private static void RegisterCustomAbiTypeMappingNoLock(
#if NET
[return: DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public static Type FindCustomHelperTypeMapping(Type publicType, bool filterToRuntimeClass = false)
Expand Down
64 changes: 42 additions & 22 deletions src/WinRT.Runtime/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ static class TypeExtensions

#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
[SuppressMessage("Trimming", "IL2073", Justification = "Matching trimming annotations are used at all callsites registering helper types present in the cache.")]
#endif
public static Type FindHelperType(this Type type)
{
#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
static Type FindHelperTypeNoCache(Type type)
Expand Down Expand Up @@ -76,7 +74,7 @@ static Type FindHelperTypeNoCache(Type type)
#if NET
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "No members of the generic type are dynamically accessed other than for the attributes on it.")]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)]
#endif
static Type GetHelperTypeFromAttribute(WindowsRuntimeHelperTypeAttribute helperTypeAtribute, Type type)
{
Expand Down Expand Up @@ -119,8 +117,7 @@ static Type FindHelperTypeFallback(Type type)
}

#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicNestedTypes |
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public static Type GetHelperType(this Type type)
Expand All @@ -140,13 +137,10 @@ public static Type GetGuidType(this Type type)
}

#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public static Type FindVftblType(
#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes)]
[UnconditionalSuppressMessage("AOT", "IL3050", Justification = "The fallback path is not AOT-safe by design (to avoid annotations).")]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The fallback path is not trim-safe by design (to avoid annotations).")]
#endif
this Type helperType)
public static Type FindVftblType(this Type helperType)
{
#if NET
if (!RuntimeFeature.IsDynamicCodeCompiled)
Expand All @@ -155,23 +149,49 @@ public static Type FindVftblType(
}
#endif

Type vftblType = helperType.GetNestedType("Vftbl");
if (vftblType is null)
{
return null;
}
if (helperType.IsGenericType && vftblType is object)
#if NET8_0_OR_GREATER
[RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)]
#endif
#if NET
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncActionWithProgress`1+Vftbl", "Microsoft.Windows.SDK.NET")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncOperationWithProgress`2+Vftbl", "Microsoft.Windows.SDK.NET")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncOperation`1+Vftbl", "Microsoft.Windows.SDK.NET")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IMapChangedEventArgs`1+Vftbl", "Microsoft.Windows.SDK.NET")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IObservableMap`2+Vftbl", "Microsoft.Windows.SDK.NET")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IObservableVector`1+Vftbl", "Microsoft.Windows.SDK.NET")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.EventHandler`1+Vftbl", "WinRT.Runtime")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.KeyValuePair`2+Vftbl", "WinRT.Runtime")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IEnumerable`1+Vftbl", "WinRT.Runtime")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IEnumerator`1+Vftbl", "WinRT.Runtime")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IList`1+Vftbl", "WinRT.Runtime")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IReadOnlyList`1+Vftbl", "WinRT.Runtime")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IDictionary`2+Vftbl", "WinRT.Runtime")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IReadOnlyDictionary`2+Vftbl", "WinRT.Runtime")]
[RequiresUnreferencedCode(AttributeMessages.GenericRequiresUnreferencedCodeMessage)]
#endif
static Type FindVftblTypeFallback(Type helperType)
{
#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273
vftblType = vftblType.MakeGenericType(helperType.GetGenericArguments());
#pragma warning restore IL3050
Type vftblType = helperType.GetNestedType("Vftbl");
if (vftblType is null)
{
return null;
}
if (helperType.IsGenericType)
{
vftblType = vftblType.MakeGenericType(helperType.GetGenericArguments());
}
return vftblType;
}
return vftblType;

return FindVftblTypeFallback(helperType);
}

#if NET
[SuppressMessage("Trimming", "IL2075", Justification = "The path using vtable types is a fallback and is not trim-safe by design.")]
#endif
internal static IntPtr GetAbiToProjectionVftblPtr(
#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes)]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
#endif
this Type helperType)
{
Expand Down

0 comments on commit 46bb1b5

Please sign in to comment.